2 function actionAddEntity(way) {
3 return function(graph) {
4 return graph.replace(way);
8 var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
10 function commonjsRequire () {
11 throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs');
16 function createCommonjsModule(fn, module) {
17 return module = { exports: {} }, fn(module, module.exports), module.exports;
20 var lodash = createCommonjsModule(function (module, exports) {
23 * Lodash <https://lodash.com/>
24 * Copyright JS Foundation and other contributors <https://js.foundation/>
25 * Released under MIT license <https://lodash.com/license>
26 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
27 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
31 /** Used as a safe reference for `undefined` in pre-ES5 environments. */
34 /** Used as the semantic version number. */
35 var VERSION = '4.17.1';
37 /** Used as the size to enable large array optimizations. */
38 var LARGE_ARRAY_SIZE = 200;
40 /** Error message constants. */
41 var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',
42 FUNC_ERROR_TEXT = 'Expected a function';
44 /** Used to stand-in for `undefined` hash values. */
45 var HASH_UNDEFINED = '__lodash_hash_undefined__';
47 /** Used as the maximum memoize cache size. */
48 var MAX_MEMOIZE_SIZE = 500;
50 /** Used as the internal argument placeholder. */
51 var PLACEHOLDER = '__lodash_placeholder__';
53 /** Used to compose bitmasks for cloning. */
54 var CLONE_DEEP_FLAG = 1,
56 CLONE_SYMBOLS_FLAG = 4;
58 /** Used to compose bitmasks for value comparisons. */
59 var COMPARE_PARTIAL_FLAG = 1,
60 COMPARE_UNORDERED_FLAG = 2;
62 /** Used to compose bitmasks for function metadata. */
63 var WRAP_BIND_FLAG = 1,
64 WRAP_BIND_KEY_FLAG = 2,
65 WRAP_CURRY_BOUND_FLAG = 4,
67 WRAP_CURRY_RIGHT_FLAG = 16,
68 WRAP_PARTIAL_FLAG = 32,
69 WRAP_PARTIAL_RIGHT_FLAG = 64,
71 WRAP_REARG_FLAG = 256,
74 /** Used as default options for `_.truncate`. */
75 var DEFAULT_TRUNC_LENGTH = 30,
76 DEFAULT_TRUNC_OMISSION = '...';
78 /** Used to detect hot functions by number of calls within a span of milliseconds. */
82 /** Used to indicate the type of lazy iteratees. */
83 var LAZY_FILTER_FLAG = 1,
87 /** Used as references for various `Number` constants. */
89 MAX_SAFE_INTEGER = 9007199254740991,
90 MAX_INTEGER = 1.7976931348623157e+308,
93 /** Used as references for the maximum length and index of an array. */
94 var MAX_ARRAY_LENGTH = 4294967295,
95 MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
96 HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
98 /** Used to associate wrap methods with their bit flags. */
100 ['ary', WRAP_ARY_FLAG],
101 ['bind', WRAP_BIND_FLAG],
102 ['bindKey', WRAP_BIND_KEY_FLAG],
103 ['curry', WRAP_CURRY_FLAG],
104 ['curryRight', WRAP_CURRY_RIGHT_FLAG],
105 ['flip', WRAP_FLIP_FLAG],
106 ['partial', WRAP_PARTIAL_FLAG],
107 ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
108 ['rearg', WRAP_REARG_FLAG]
111 /** `Object#toString` result references. */
112 var argsTag = '[object Arguments]',
113 arrayTag = '[object Array]',
114 asyncTag = '[object AsyncFunction]',
115 boolTag = '[object Boolean]',
116 dateTag = '[object Date]',
117 domExcTag = '[object DOMException]',
118 errorTag = '[object Error]',
119 funcTag = '[object Function]',
120 genTag = '[object GeneratorFunction]',
121 mapTag = '[object Map]',
122 numberTag = '[object Number]',
123 nullTag = '[object Null]',
124 objectTag = '[object Object]',
125 promiseTag = '[object Promise]',
126 proxyTag = '[object Proxy]',
127 regexpTag = '[object RegExp]',
128 setTag = '[object Set]',
129 stringTag = '[object String]',
130 symbolTag = '[object Symbol]',
131 undefinedTag = '[object Undefined]',
132 weakMapTag = '[object WeakMap]',
133 weakSetTag = '[object WeakSet]';
135 var arrayBufferTag = '[object ArrayBuffer]',
136 dataViewTag = '[object DataView]',
137 float32Tag = '[object Float32Array]',
138 float64Tag = '[object Float64Array]',
139 int8Tag = '[object Int8Array]',
140 int16Tag = '[object Int16Array]',
141 int32Tag = '[object Int32Array]',
142 uint8Tag = '[object Uint8Array]',
143 uint8ClampedTag = '[object Uint8ClampedArray]',
144 uint16Tag = '[object Uint16Array]',
145 uint32Tag = '[object Uint32Array]';
147 /** Used to match empty string literals in compiled template source. */
148 var reEmptyStringLeading = /\b__p \+= '';/g,
149 reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
150 reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
152 /** Used to match HTML entities and HTML characters. */
153 var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
154 reUnescapedHtml = /[&<>"']/g,
155 reHasEscapedHtml = RegExp(reEscapedHtml.source),
156 reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
158 /** Used to match template delimiters. */
159 var reEscape = /<%-([\s\S]+?)%>/g,
160 reEvaluate = /<%([\s\S]+?)%>/g,
161 reInterpolate = /<%=([\s\S]+?)%>/g;
163 /** Used to match property names within property paths. */
164 var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
165 reIsPlainProp = /^\w*$/,
166 reLeadingDot = /^\./,
167 rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
170 * Used to match `RegExp`
171 * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
173 var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
174 reHasRegExpChar = RegExp(reRegExpChar.source);
176 /** Used to match leading and trailing whitespace. */
177 var reTrim = /^\s+|\s+$/g,
178 reTrimStart = /^\s+/,
181 /** Used to match wrap detail comments. */
182 var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
183 reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
184 reSplitDetails = /,? & /;
186 /** Used to match words composed of alphanumeric characters. */
187 var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
189 /** Used to match backslashes in property paths. */
190 var reEscapeChar = /\\(\\)?/g;
194 * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
196 var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
198 /** Used to match `RegExp` flags from their coerced string values. */
199 var reFlags = /\w*$/;
201 /** Used to detect bad signed hexadecimal string values. */
202 var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
204 /** Used to detect binary string values. */
205 var reIsBinary = /^0b[01]+$/i;
207 /** Used to detect host constructors (Safari). */
208 var reIsHostCtor = /^\[object .+?Constructor\]$/;
210 /** Used to detect octal string values. */
211 var reIsOctal = /^0o[0-7]+$/i;
213 /** Used to detect unsigned integer values. */
214 var reIsUint = /^(?:0|[1-9]\d*)$/;
216 /** Used to match Latin Unicode letters (excluding mathematical operators). */
217 var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
219 /** Used to ensure capturing order of template delimiters. */
220 var reNoMatch = /($^)/;
222 /** Used to match unescaped characters in compiled string literals. */
223 var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
225 /** Used to compose unicode character classes. */
226 var rsAstralRange = '\\ud800-\\udfff',
227 rsComboMarksRange = '\\u0300-\\u036f',
228 reComboHalfMarksRange = '\\ufe20-\\ufe2f',
229 rsComboSymbolsRange = '\\u20d0-\\u20ff',
230 rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
231 rsDingbatRange = '\\u2700-\\u27bf',
232 rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
233 rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
234 rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
235 rsPunctuationRange = '\\u2000-\\u206f',
236 rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
237 rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
238 rsVarRange = '\\ufe0e\\ufe0f',
239 rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
241 /** Used to compose unicode capture groups. */
242 var rsApos = "['\u2019]",
243 rsAstral = '[' + rsAstralRange + ']',
244 rsBreak = '[' + rsBreakRange + ']',
245 rsCombo = '[' + rsComboRange + ']',
247 rsDingbat = '[' + rsDingbatRange + ']',
248 rsLower = '[' + rsLowerRange + ']',
249 rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
250 rsFitz = '\\ud83c[\\udffb-\\udfff]',
251 rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
252 rsNonAstral = '[^' + rsAstralRange + ']',
253 rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
254 rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
255 rsUpper = '[' + rsUpperRange + ']',
258 /** Used to compose unicode regexes. */
259 var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',
260 rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',
261 rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
262 rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
263 reOptMod = rsModifier + '?',
264 rsOptVar = '[' + rsVarRange + ']?',
265 rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
266 rsOrdLower = '\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)',
267 rsOrdUpper = '\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)',
268 rsSeq = rsOptVar + reOptMod + rsOptJoin,
269 rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
270 rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
272 /** Used to match apostrophes. */
273 var reApos = RegExp(rsApos, 'g');
276 * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
277 * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
279 var reComboMark = RegExp(rsCombo, 'g');
281 /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
282 var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
284 /** Used to match complex or compound words. */
285 var reUnicodeWord = RegExp([
286 rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
287 rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',
288 rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,
289 rsUpper + '+' + rsOptContrUpper,
296 /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
297 var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
299 /** Used to detect strings that need a more robust regexp to match words. */
300 var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
302 /** Used to assign default `context` object properties. */
304 'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
305 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
306 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
307 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
308 '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
311 /** Used to make template sourceURLs easier to identify. */
312 var templateCounter = -1;
314 /** Used to identify `toStringTag` values of typed arrays. */
315 var typedArrayTags = {};
316 typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
317 typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
318 typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
319 typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
320 typedArrayTags[uint32Tag] = true;
321 typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
322 typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
323 typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
324 typedArrayTags[errorTag] = typedArrayTags[funcTag] =
325 typedArrayTags[mapTag] = typedArrayTags[numberTag] =
326 typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
327 typedArrayTags[setTag] = typedArrayTags[stringTag] =
328 typedArrayTags[weakMapTag] = false;
330 /** Used to identify `toStringTag` values supported by `_.clone`. */
331 var cloneableTags = {};
332 cloneableTags[argsTag] = cloneableTags[arrayTag] =
333 cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
334 cloneableTags[boolTag] = cloneableTags[dateTag] =
335 cloneableTags[float32Tag] = cloneableTags[float64Tag] =
336 cloneableTags[int8Tag] = cloneableTags[int16Tag] =
337 cloneableTags[int32Tag] = cloneableTags[mapTag] =
338 cloneableTags[numberTag] = cloneableTags[objectTag] =
339 cloneableTags[regexpTag] = cloneableTags[setTag] =
340 cloneableTags[stringTag] = cloneableTags[symbolTag] =
341 cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
342 cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
343 cloneableTags[errorTag] = cloneableTags[funcTag] =
344 cloneableTags[weakMapTag] = false;
346 /** Used to map Latin Unicode letters to basic Latin letters. */
347 var deburredLetters = {
348 // Latin-1 Supplement block.
349 '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
350 '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
351 '\xc7': 'C', '\xe7': 'c',
352 '\xd0': 'D', '\xf0': 'd',
353 '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
354 '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
355 '\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
356 '\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i',
357 '\xd1': 'N', '\xf1': 'n',
358 '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
359 '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
360 '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
361 '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
362 '\xdd': 'Y', '\xfd': 'y', '\xff': 'y',
363 '\xc6': 'Ae', '\xe6': 'ae',
364 '\xde': 'Th', '\xfe': 'th',
366 // Latin Extended-A block.
367 '\u0100': 'A', '\u0102': 'A', '\u0104': 'A',
368 '\u0101': 'a', '\u0103': 'a', '\u0105': 'a',
369 '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
370 '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
371 '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
372 '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
373 '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
374 '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
375 '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
376 '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
377 '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
378 '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
379 '\u0134': 'J', '\u0135': 'j',
380 '\u0136': 'K', '\u0137': 'k', '\u0138': 'k',
381 '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
382 '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
383 '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
384 '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
385 '\u014c': 'O', '\u014e': 'O', '\u0150': 'O',
386 '\u014d': 'o', '\u014f': 'o', '\u0151': 'o',
387 '\u0154': 'R', '\u0156': 'R', '\u0158': 'R',
388 '\u0155': 'r', '\u0157': 'r', '\u0159': 'r',
389 '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
390 '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's',
391 '\u0162': 'T', '\u0164': 'T', '\u0166': 'T',
392 '\u0163': 't', '\u0165': 't', '\u0167': 't',
393 '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
394 '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
395 '\u0174': 'W', '\u0175': 'w',
396 '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y',
397 '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z',
398 '\u017a': 'z', '\u017c': 'z', '\u017e': 'z',
399 '\u0132': 'IJ', '\u0133': 'ij',
400 '\u0152': 'Oe', '\u0153': 'oe',
401 '\u0149': "'n", '\u017f': 's'
404 /** Used to map characters to HTML entities. */
413 /** Used to map HTML entities to characters. */
414 var htmlUnescapes = {
422 /** Used to escape characters for inclusion in compiled string literals. */
423 var stringEscapes = {
432 /** Built-in method references without a dependency on `root`. */
433 var freeParseFloat = parseFloat,
434 freeParseInt = parseInt;
436 /** Detect free variable `global` from Node.js. */
437 var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
439 /** Detect free variable `self`. */
440 var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
442 /** Used as a reference to the global object. */
443 var root = freeGlobal || freeSelf || Function('return this')();
445 /** Detect free variable `exports`. */
446 var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
448 /** Detect free variable `module`. */
449 var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
451 /** Detect the popular CommonJS extension `module.exports`. */
452 var moduleExports = freeModule && freeModule.exports === freeExports;
454 /** Detect free variable `process` from Node.js. */
455 var freeProcess = moduleExports && freeGlobal.process;
457 /** Used to access faster Node.js helpers. */
458 var nodeUtil = (function() {
460 return freeProcess && freeProcess.binding && freeProcess.binding('util');
464 /* Node.js helper references. */
465 var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,
466 nodeIsDate = nodeUtil && nodeUtil.isDate,
467 nodeIsMap = nodeUtil && nodeUtil.isMap,
468 nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,
469 nodeIsSet = nodeUtil && nodeUtil.isSet,
470 nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
472 /*--------------------------------------------------------------------------*/
475 * Adds the key-value `pair` to `map`.
478 * @param {Object} map The map to modify.
479 * @param {Array} pair The key-value pair to add.
480 * @returns {Object} Returns `map`.
482 function addMapEntry(map, pair) {
483 // Don't return `map.set` because it's not chainable in IE 11.
484 map.set(pair[0], pair[1]);
489 * Adds `value` to `set`.
492 * @param {Object} set The set to modify.
493 * @param {*} value The value to add.
494 * @returns {Object} Returns `set`.
496 function addSetEntry(set, value) {
497 // Don't return `set.add` because it's not chainable in IE 11.
503 * A faster alternative to `Function#apply`, this function invokes `func`
504 * with the `this` binding of `thisArg` and the arguments of `args`.
507 * @param {Function} func The function to invoke.
508 * @param {*} thisArg The `this` binding of `func`.
509 * @param {Array} args The arguments to invoke `func` with.
510 * @returns {*} Returns the result of `func`.
512 function apply(func, thisArg, args) {
513 switch (args.length) {
514 case 0: return func.call(thisArg);
515 case 1: return func.call(thisArg, args[0]);
516 case 2: return func.call(thisArg, args[0], args[1]);
517 case 3: return func.call(thisArg, args[0], args[1], args[2]);
519 return func.apply(thisArg, args);
523 * A specialized version of `baseAggregator` for arrays.
526 * @param {Array} [array] The array to iterate over.
527 * @param {Function} setter The function to set `accumulator` values.
528 * @param {Function} iteratee The iteratee to transform keys.
529 * @param {Object} accumulator The initial aggregated object.
530 * @returns {Function} Returns `accumulator`.
532 function arrayAggregator(array, setter, iteratee, accumulator) {
534 length = array == null ? 0 : array.length;
536 while (++index < length) {
537 var value = array[index];
538 setter(accumulator, value, iteratee(value), array);
544 * A specialized version of `_.forEach` for arrays without support for
545 * iteratee shorthands.
548 * @param {Array} [array] The array to iterate over.
549 * @param {Function} iteratee The function invoked per iteration.
550 * @returns {Array} Returns `array`.
552 function arrayEach(array, iteratee) {
554 length = array == null ? 0 : array.length;
556 while (++index < length) {
557 if (iteratee(array[index], index, array) === false) {
565 * A specialized version of `_.forEachRight` for arrays without support for
566 * iteratee shorthands.
569 * @param {Array} [array] The array to iterate over.
570 * @param {Function} iteratee The function invoked per iteration.
571 * @returns {Array} Returns `array`.
573 function arrayEachRight(array, iteratee) {
574 var length = array == null ? 0 : array.length;
577 if (iteratee(array[length], length, array) === false) {
585 * A specialized version of `_.every` for arrays without support for
586 * iteratee shorthands.
589 * @param {Array} [array] The array to iterate over.
590 * @param {Function} predicate The function invoked per iteration.
591 * @returns {boolean} Returns `true` if all elements pass the predicate check,
594 function arrayEvery(array, predicate) {
596 length = array == null ? 0 : array.length;
598 while (++index < length) {
599 if (!predicate(array[index], index, array)) {
607 * A specialized version of `_.filter` for arrays without support for
608 * iteratee shorthands.
611 * @param {Array} [array] The array to iterate over.
612 * @param {Function} predicate The function invoked per iteration.
613 * @returns {Array} Returns the new filtered array.
615 function arrayFilter(array, predicate) {
617 length = array == null ? 0 : array.length,
621 while (++index < length) {
622 var value = array[index];
623 if (predicate(value, index, array)) {
624 result[resIndex++] = value;
631 * A specialized version of `_.includes` for arrays without support for
632 * specifying an index to search from.
635 * @param {Array} [array] The array to inspect.
636 * @param {*} target The value to search for.
637 * @returns {boolean} Returns `true` if `target` is found, else `false`.
639 function arrayIncludes(array, value) {
640 var length = array == null ? 0 : array.length;
641 return !!length && baseIndexOf(array, value, 0) > -1;
645 * This function is like `arrayIncludes` except that it accepts a comparator.
648 * @param {Array} [array] The array to inspect.
649 * @param {*} target The value to search for.
650 * @param {Function} comparator The comparator invoked per element.
651 * @returns {boolean} Returns `true` if `target` is found, else `false`.
653 function arrayIncludesWith(array, value, comparator) {
655 length = array == null ? 0 : array.length;
657 while (++index < length) {
658 if (comparator(value, array[index])) {
666 * A specialized version of `_.map` for arrays without support for iteratee
670 * @param {Array} [array] The array to iterate over.
671 * @param {Function} iteratee The function invoked per iteration.
672 * @returns {Array} Returns the new mapped array.
674 function arrayMap(array, iteratee) {
676 length = array == null ? 0 : array.length,
677 result = Array(length);
679 while (++index < length) {
680 result[index] = iteratee(array[index], index, array);
686 * Appends the elements of `values` to `array`.
689 * @param {Array} array The array to modify.
690 * @param {Array} values The values to append.
691 * @returns {Array} Returns `array`.
693 function arrayPush(array, values) {
695 length = values.length,
696 offset = array.length;
698 while (++index < length) {
699 array[offset + index] = values[index];
705 * A specialized version of `_.reduce` for arrays without support for
706 * iteratee shorthands.
709 * @param {Array} [array] The array to iterate over.
710 * @param {Function} iteratee The function invoked per iteration.
711 * @param {*} [accumulator] The initial value.
712 * @param {boolean} [initAccum] Specify using the first element of `array` as
714 * @returns {*} Returns the accumulated value.
716 function arrayReduce(array, iteratee, accumulator, initAccum) {
718 length = array == null ? 0 : array.length;
720 if (initAccum && length) {
721 accumulator = array[++index];
723 while (++index < length) {
724 accumulator = iteratee(accumulator, array[index], index, array);
730 * A specialized version of `_.reduceRight` for arrays without support for
731 * iteratee shorthands.
734 * @param {Array} [array] The array to iterate over.
735 * @param {Function} iteratee The function invoked per iteration.
736 * @param {*} [accumulator] The initial value.
737 * @param {boolean} [initAccum] Specify using the last element of `array` as
739 * @returns {*} Returns the accumulated value.
741 function arrayReduceRight(array, iteratee, accumulator, initAccum) {
742 var length = array == null ? 0 : array.length;
743 if (initAccum && length) {
744 accumulator = array[--length];
747 accumulator = iteratee(accumulator, array[length], length, array);
753 * A specialized version of `_.some` for arrays without support for iteratee
757 * @param {Array} [array] The array to iterate over.
758 * @param {Function} predicate The function invoked per iteration.
759 * @returns {boolean} Returns `true` if any element passes the predicate check,
762 function arraySome(array, predicate) {
764 length = array == null ? 0 : array.length;
766 while (++index < length) {
767 if (predicate(array[index], index, array)) {
775 * Gets the size of an ASCII `string`.
778 * @param {string} string The string inspect.
779 * @returns {number} Returns the string size.
781 var asciiSize = baseProperty('length');
784 * Converts an ASCII `string` to an array.
787 * @param {string} string The string to convert.
788 * @returns {Array} Returns the converted array.
790 function asciiToArray(string) {
791 return string.split('');
795 * Splits an ASCII `string` into an array of its words.
798 * @param {string} The string to inspect.
799 * @returns {Array} Returns the words of `string`.
801 function asciiWords(string) {
802 return string.match(reAsciiWord) || [];
806 * The base implementation of methods like `_.findKey` and `_.findLastKey`,
807 * without support for iteratee shorthands, which iterates over `collection`
811 * @param {Array|Object} collection The collection to inspect.
812 * @param {Function} predicate The function invoked per iteration.
813 * @param {Function} eachFunc The function to iterate over `collection`.
814 * @returns {*} Returns the found element or its key, else `undefined`.
816 function baseFindKey(collection, predicate, eachFunc) {
818 eachFunc(collection, function(value, key, collection) {
819 if (predicate(value, key, collection)) {
828 * The base implementation of `_.findIndex` and `_.findLastIndex` without
829 * support for iteratee shorthands.
832 * @param {Array} array The array to inspect.
833 * @param {Function} predicate The function invoked per iteration.
834 * @param {number} fromIndex The index to search from.
835 * @param {boolean} [fromRight] Specify iterating from right to left.
836 * @returns {number} Returns the index of the matched value, else `-1`.
838 function baseFindIndex(array, predicate, fromIndex, fromRight) {
839 var length = array.length,
840 index = fromIndex + (fromRight ? 1 : -1);
842 while ((fromRight ? index-- : ++index < length)) {
843 if (predicate(array[index], index, array)) {
851 * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
854 * @param {Array} array The array to inspect.
855 * @param {*} value The value to search for.
856 * @param {number} fromIndex The index to search from.
857 * @returns {number} Returns the index of the matched value, else `-1`.
859 function baseIndexOf(array, value, fromIndex) {
860 return value === value
861 ? strictIndexOf(array, value, fromIndex)
862 : baseFindIndex(array, baseIsNaN, fromIndex);
866 * This function is like `baseIndexOf` except that it accepts a comparator.
869 * @param {Array} array The array to inspect.
870 * @param {*} value The value to search for.
871 * @param {number} fromIndex The index to search from.
872 * @param {Function} comparator The comparator invoked per element.
873 * @returns {number} Returns the index of the matched value, else `-1`.
875 function baseIndexOfWith(array, value, fromIndex, comparator) {
876 var index = fromIndex - 1,
877 length = array.length;
879 while (++index < length) {
880 if (comparator(array[index], value)) {
888 * The base implementation of `_.isNaN` without support for number objects.
891 * @param {*} value The value to check.
892 * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
894 function baseIsNaN(value) {
895 return value !== value;
899 * The base implementation of `_.mean` and `_.meanBy` without support for
900 * iteratee shorthands.
903 * @param {Array} array The array to iterate over.
904 * @param {Function} iteratee The function invoked per iteration.
905 * @returns {number} Returns the mean.
907 function baseMean(array, iteratee) {
908 var length = array == null ? 0 : array.length;
909 return length ? (baseSum(array, iteratee) / length) : NAN;
913 * The base implementation of `_.property` without support for deep paths.
916 * @param {string} key The key of the property to get.
917 * @returns {Function} Returns the new accessor function.
919 function baseProperty(key) {
920 return function(object) {
921 return object == null ? undefined : object[key];
926 * The base implementation of `_.propertyOf` without support for deep paths.
929 * @param {Object} object The object to query.
930 * @returns {Function} Returns the new accessor function.
932 function basePropertyOf(object) {
933 return function(key) {
934 return object == null ? undefined : object[key];
939 * The base implementation of `_.reduce` and `_.reduceRight`, without support
940 * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
943 * @param {Array|Object} collection The collection to iterate over.
944 * @param {Function} iteratee The function invoked per iteration.
945 * @param {*} accumulator The initial value.
946 * @param {boolean} initAccum Specify using the first or last element of
947 * `collection` as the initial value.
948 * @param {Function} eachFunc The function to iterate over `collection`.
949 * @returns {*} Returns the accumulated value.
951 function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
952 eachFunc(collection, function(value, index, collection) {
953 accumulator = initAccum
954 ? (initAccum = false, value)
955 : iteratee(accumulator, value, index, collection);
961 * The base implementation of `_.sortBy` which uses `comparer` to define the
962 * sort order of `array` and replaces criteria objects with their corresponding
966 * @param {Array} array The array to sort.
967 * @param {Function} comparer The function to define sort order.
968 * @returns {Array} Returns `array`.
970 function baseSortBy(array, comparer) {
971 var length = array.length;
973 array.sort(comparer);
975 array[length] = array[length].value;
981 * The base implementation of `_.sum` and `_.sumBy` without support for
982 * iteratee shorthands.
985 * @param {Array} array The array to iterate over.
986 * @param {Function} iteratee The function invoked per iteration.
987 * @returns {number} Returns the sum.
989 function baseSum(array, iteratee) {
992 length = array.length;
994 while (++index < length) {
995 var current = iteratee(array[index]);
996 if (current !== undefined) {
997 result = result === undefined ? current : (result + current);
1004 * The base implementation of `_.times` without support for iteratee shorthands
1005 * or max array length checks.
1008 * @param {number} n The number of times to invoke `iteratee`.
1009 * @param {Function} iteratee The function invoked per iteration.
1010 * @returns {Array} Returns the array of results.
1012 function baseTimes(n, iteratee) {
1016 while (++index < n) {
1017 result[index] = iteratee(index);
1023 * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
1024 * of key-value pairs for `object` corresponding to the property names of `props`.
1027 * @param {Object} object The object to query.
1028 * @param {Array} props The property names to get values for.
1029 * @returns {Object} Returns the key-value pairs.
1031 function baseToPairs(object, props) {
1032 return arrayMap(props, function(key) {
1033 return [key, object[key]];
1038 * The base implementation of `_.unary` without support for storing metadata.
1041 * @param {Function} func The function to cap arguments for.
1042 * @returns {Function} Returns the new capped function.
1044 function baseUnary(func) {
1045 return function(value) {
1051 * The base implementation of `_.values` and `_.valuesIn` which creates an
1052 * array of `object` property values corresponding to the property names
1056 * @param {Object} object The object to query.
1057 * @param {Array} props The property names to get values for.
1058 * @returns {Object} Returns the array of property values.
1060 function baseValues(object, props) {
1061 return arrayMap(props, function(key) {
1067 * Checks if a `cache` value for `key` exists.
1070 * @param {Object} cache The cache to query.
1071 * @param {string} key The key of the entry to check.
1072 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1074 function cacheHas(cache, key) {
1075 return cache.has(key);
1079 * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
1080 * that is not found in the character symbols.
1083 * @param {Array} strSymbols The string symbols to inspect.
1084 * @param {Array} chrSymbols The character symbols to find.
1085 * @returns {number} Returns the index of the first unmatched string symbol.
1087 function charsStartIndex(strSymbols, chrSymbols) {
1089 length = strSymbols.length;
1091 while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
1096 * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
1097 * that is not found in the character symbols.
1100 * @param {Array} strSymbols The string symbols to inspect.
1101 * @param {Array} chrSymbols The character symbols to find.
1102 * @returns {number} Returns the index of the last unmatched string symbol.
1104 function charsEndIndex(strSymbols, chrSymbols) {
1105 var index = strSymbols.length;
1107 while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
1112 * Gets the number of `placeholder` occurrences in `array`.
1115 * @param {Array} array The array to inspect.
1116 * @param {*} placeholder The placeholder to search for.
1117 * @returns {number} Returns the placeholder count.
1119 function countHolders(array, placeholder) {
1120 var length = array.length,
1124 if (array[length] === placeholder) {
1132 * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
1133 * letters to basic Latin letters.
1136 * @param {string} letter The matched letter to deburr.
1137 * @returns {string} Returns the deburred letter.
1139 var deburrLetter = basePropertyOf(deburredLetters);
1142 * Used by `_.escape` to convert characters to HTML entities.
1145 * @param {string} chr The matched character to escape.
1146 * @returns {string} Returns the escaped character.
1148 var escapeHtmlChar = basePropertyOf(htmlEscapes);
1151 * Used by `_.template` to escape characters for inclusion in compiled string literals.
1154 * @param {string} chr The matched character to escape.
1155 * @returns {string} Returns the escaped character.
1157 function escapeStringChar(chr) {
1158 return '\\' + stringEscapes[chr];
1162 * Gets the value at `key` of `object`.
1165 * @param {Object} [object] The object to query.
1166 * @param {string} key The key of the property to get.
1167 * @returns {*} Returns the property value.
1169 function getValue(object, key) {
1170 return object == null ? undefined : object[key];
1174 * Checks if `string` contains Unicode symbols.
1177 * @param {string} string The string to inspect.
1178 * @returns {boolean} Returns `true` if a symbol is found, else `false`.
1180 function hasUnicode(string) {
1181 return reHasUnicode.test(string);
1185 * Checks if `string` contains a word composed of Unicode symbols.
1188 * @param {string} string The string to inspect.
1189 * @returns {boolean} Returns `true` if a word is found, else `false`.
1191 function hasUnicodeWord(string) {
1192 return reHasUnicodeWord.test(string);
1196 * Converts `iterator` to an array.
1199 * @param {Object} iterator The iterator to convert.
1200 * @returns {Array} Returns the converted array.
1202 function iteratorToArray(iterator) {
1206 while (!(data = iterator.next()).done) {
1207 result.push(data.value);
1213 * Converts `map` to its key-value pairs.
1216 * @param {Object} map The map to convert.
1217 * @returns {Array} Returns the key-value pairs.
1219 function mapToArray(map) {
1221 result = Array(map.size);
1223 map.forEach(function(value, key) {
1224 result[++index] = [key, value];
1230 * Creates a unary function that invokes `func` with its argument transformed.
1233 * @param {Function} func The function to wrap.
1234 * @param {Function} transform The argument transform.
1235 * @returns {Function} Returns the new function.
1237 function overArg(func, transform) {
1238 return function(arg) {
1239 return func(transform(arg));
1244 * Replaces all `placeholder` elements in `array` with an internal placeholder
1245 * and returns an array of their indexes.
1248 * @param {Array} array The array to modify.
1249 * @param {*} placeholder The placeholder to replace.
1250 * @returns {Array} Returns the new array of placeholder indexes.
1252 function replaceHolders(array, placeholder) {
1254 length = array.length,
1258 while (++index < length) {
1259 var value = array[index];
1260 if (value === placeholder || value === PLACEHOLDER) {
1261 array[index] = PLACEHOLDER;
1262 result[resIndex++] = index;
1269 * Converts `set` to an array of its values.
1272 * @param {Object} set The set to convert.
1273 * @returns {Array} Returns the values.
1275 function setToArray(set) {
1277 result = Array(set.size);
1279 set.forEach(function(value) {
1280 result[++index] = value;
1286 * Converts `set` to its value-value pairs.
1289 * @param {Object} set The set to convert.
1290 * @returns {Array} Returns the value-value pairs.
1292 function setToPairs(set) {
1294 result = Array(set.size);
1296 set.forEach(function(value) {
1297 result[++index] = [value, value];
1303 * A specialized version of `_.indexOf` which performs strict equality
1304 * comparisons of values, i.e. `===`.
1307 * @param {Array} array The array to inspect.
1308 * @param {*} value The value to search for.
1309 * @param {number} fromIndex The index to search from.
1310 * @returns {number} Returns the index of the matched value, else `-1`.
1312 function strictIndexOf(array, value, fromIndex) {
1313 var index = fromIndex - 1,
1314 length = array.length;
1316 while (++index < length) {
1317 if (array[index] === value) {
1325 * A specialized version of `_.lastIndexOf` which performs strict equality
1326 * comparisons of values, i.e. `===`.
1329 * @param {Array} array The array to inspect.
1330 * @param {*} value The value to search for.
1331 * @param {number} fromIndex The index to search from.
1332 * @returns {number} Returns the index of the matched value, else `-1`.
1334 function strictLastIndexOf(array, value, fromIndex) {
1335 var index = fromIndex + 1;
1337 if (array[index] === value) {
1345 * Gets the number of symbols in `string`.
1348 * @param {string} string The string to inspect.
1349 * @returns {number} Returns the string size.
1351 function stringSize(string) {
1352 return hasUnicode(string)
1353 ? unicodeSize(string)
1354 : asciiSize(string);
1358 * Converts `string` to an array.
1361 * @param {string} string The string to convert.
1362 * @returns {Array} Returns the converted array.
1364 function stringToArray(string) {
1365 return hasUnicode(string)
1366 ? unicodeToArray(string)
1367 : asciiToArray(string);
1371 * Used by `_.unescape` to convert HTML entities to characters.
1374 * @param {string} chr The matched character to unescape.
1375 * @returns {string} Returns the unescaped character.
1377 var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
1380 * Gets the size of a Unicode `string`.
1383 * @param {string} string The string inspect.
1384 * @returns {number} Returns the string size.
1386 function unicodeSize(string) {
1387 var result = reUnicode.lastIndex = 0;
1388 while (reUnicode.test(string)) {
1395 * Converts a Unicode `string` to an array.
1398 * @param {string} string The string to convert.
1399 * @returns {Array} Returns the converted array.
1401 function unicodeToArray(string) {
1402 return string.match(reUnicode) || [];
1406 * Splits a Unicode `string` into an array of its words.
1409 * @param {string} The string to inspect.
1410 * @returns {Array} Returns the words of `string`.
1412 function unicodeWords(string) {
1413 return string.match(reUnicodeWord) || [];
1416 /*--------------------------------------------------------------------------*/
1419 * Create a new pristine `lodash` function using the `context` object.
1425 * @param {Object} [context=root] The context object.
1426 * @returns {Function} Returns a new `lodash` function.
1429 * _.mixin({ 'foo': _.constant('foo') });
1431 * var lodash = _.runInContext();
1432 * lodash.mixin({ 'bar': lodash.constant('bar') });
1434 * _.isFunction(_.foo);
1436 * _.isFunction(_.bar);
1439 * lodash.isFunction(lodash.foo);
1441 * lodash.isFunction(lodash.bar);
1444 * // Create a suped-up `defer` in Node.js.
1445 * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
1447 var runInContext = (function runInContext(context) {
1448 context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
1450 /** Built-in constructor references. */
1451 var Array = context.Array,
1452 Date = context.Date,
1453 Error = context.Error,
1454 Function = context.Function,
1455 Math = context.Math,
1456 Object = context.Object,
1457 RegExp = context.RegExp,
1458 String = context.String,
1459 TypeError = context.TypeError;
1461 /** Used for built-in method references. */
1462 var arrayProto = Array.prototype,
1463 funcProto = Function.prototype,
1464 objectProto = Object.prototype;
1466 /** Used to detect overreaching core-js shims. */
1467 var coreJsData = context['__core-js_shared__'];
1469 /** Used to resolve the decompiled source of functions. */
1470 var funcToString = funcProto.toString;
1472 /** Used to check objects for own properties. */
1473 var hasOwnProperty = objectProto.hasOwnProperty;
1475 /** Used to generate unique IDs. */
1478 /** Used to detect methods masquerading as native. */
1479 var maskSrcKey = (function() {
1480 var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
1481 return uid ? ('Symbol(src)_1.' + uid) : '';
1485 * Used to resolve the
1486 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
1489 var nativeObjectToString = objectProto.toString;
1491 /** Used to infer the `Object` constructor. */
1492 var objectCtorString = funcToString.call(Object);
1494 /** Used to restore the original `_` reference in `_.noConflict`. */
1495 var oldDash = root._;
1497 /** Used to detect if a method is native. */
1498 var reIsNative = RegExp('^' +
1499 funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
1500 .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
1503 /** Built-in value references. */
1504 var Buffer = moduleExports ? context.Buffer : undefined,
1505 Symbol = context.Symbol,
1506 Uint8Array = context.Uint8Array,
1507 allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,
1508 getPrototype = overArg(Object.getPrototypeOf, Object),
1509 objectCreate = Object.create,
1510 propertyIsEnumerable = objectProto.propertyIsEnumerable,
1511 splice = arrayProto.splice,
1512 spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,
1513 symIterator = Symbol ? Symbol.iterator : undefined,
1514 symToStringTag = Symbol ? Symbol.toStringTag : undefined;
1516 var defineProperty = (function() {
1518 var func = getNative(Object, 'defineProperty');
1524 /** Mocked built-ins. */
1525 var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,
1526 ctxNow = Date && Date.now !== root.Date.now && Date.now,
1527 ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
1529 /* Built-in method references for those with the same name as other `lodash` methods. */
1530 var nativeCeil = Math.ceil,
1531 nativeFloor = Math.floor,
1532 nativeGetSymbols = Object.getOwnPropertySymbols,
1533 nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
1534 nativeIsFinite = context.isFinite,
1535 nativeJoin = arrayProto.join,
1536 nativeKeys = overArg(Object.keys, Object),
1537 nativeMax = Math.max,
1538 nativeMin = Math.min,
1539 nativeNow = Date.now,
1540 nativeParseInt = context.parseInt,
1541 nativeRandom = Math.random,
1542 nativeReverse = arrayProto.reverse;
1544 /* Built-in method references that are verified to be native. */
1545 var DataView = getNative(context, 'DataView'),
1546 Map = getNative(context, 'Map'),
1547 Promise = getNative(context, 'Promise'),
1548 Set = getNative(context, 'Set'),
1549 WeakMap = getNative(context, 'WeakMap'),
1550 nativeCreate = getNative(Object, 'create');
1552 /** Used to store function metadata. */
1553 var metaMap = WeakMap && new WeakMap;
1555 /** Used to lookup unminified function names. */
1558 /** Used to detect maps, sets, and weakmaps. */
1559 var dataViewCtorString = toSource(DataView),
1560 mapCtorString = toSource(Map),
1561 promiseCtorString = toSource(Promise),
1562 setCtorString = toSource(Set),
1563 weakMapCtorString = toSource(WeakMap);
1565 /** Used to convert symbols to primitives and strings. */
1566 var symbolProto = Symbol ? Symbol.prototype : undefined,
1567 symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
1568 symbolToString = symbolProto ? symbolProto.toString : undefined;
1570 /*------------------------------------------------------------------------*/
1573 * Creates a `lodash` object which wraps `value` to enable implicit method
1574 * chain sequences. Methods that operate on and return arrays, collections,
1575 * and functions can be chained together. Methods that retrieve a single value
1576 * or may return a primitive value will automatically end the chain sequence
1577 * and return the unwrapped value. Otherwise, the value must be unwrapped
1580 * Explicit chain sequences, which must be unwrapped with `_#value`, may be
1581 * enabled using `_.chain`.
1583 * The execution of chained methods is lazy, that is, it's deferred until
1584 * `_#value` is implicitly or explicitly called.
1586 * Lazy evaluation allows several methods to support shortcut fusion.
1587 * Shortcut fusion is an optimization to merge iteratee calls; this avoids
1588 * the creation of intermediate arrays and can greatly reduce the number of
1589 * iteratee executions. Sections of a chain sequence qualify for shortcut
1590 * fusion if the section is applied to an array of at least `200` elements
1591 * and any iteratees accept only one argument. The heuristic for whether a
1592 * section qualifies for shortcut fusion is subject to change.
1594 * Chaining is supported in custom builds as long as the `_#value` method is
1595 * directly or indirectly included in the build.
1597 * In addition to lodash methods, wrappers have `Array` and `String` methods.
1599 * The wrapper `Array` methods are:
1600 * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
1602 * The wrapper `String` methods are:
1603 * `replace` and `split`
1605 * The wrapper methods that support shortcut fusion are:
1606 * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
1607 * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
1608 * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
1610 * The chainable wrapper methods are:
1611 * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
1612 * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
1613 * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
1614 * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
1615 * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
1616 * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
1617 * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
1618 * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
1619 * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
1620 * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
1621 * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
1622 * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
1623 * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
1624 * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
1625 * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
1626 * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
1627 * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
1628 * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
1629 * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
1630 * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
1631 * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
1632 * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
1633 * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
1634 * `zipObject`, `zipObjectDeep`, and `zipWith`
1636 * The wrapper methods that are **not** chainable by default are:
1637 * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
1638 * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
1639 * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
1640 * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
1641 * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
1642 * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
1643 * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
1644 * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
1645 * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
1646 * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
1647 * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
1648 * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
1649 * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
1650 * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
1651 * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
1652 * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
1653 * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
1654 * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
1655 * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
1656 * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
1657 * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
1658 * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
1659 * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
1660 * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
1661 * `upperFirst`, `value`, and `words`
1666 * @param {*} value The value to wrap in a `lodash` instance.
1667 * @returns {Object} Returns the new `lodash` wrapper instance.
1670 * function square(n) {
1674 * var wrapped = _([1, 2, 3]);
1676 * // Returns an unwrapped value.
1677 * wrapped.reduce(_.add);
1680 * // Returns a wrapped value.
1681 * var squares = wrapped.map(square);
1683 * _.isArray(squares);
1686 * _.isArray(squares.value());
1689 function lodash(value) {
1690 if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
1691 if (value instanceof LodashWrapper) {
1694 if (hasOwnProperty.call(value, '__wrapped__')) {
1695 return wrapperClone(value);
1698 return new LodashWrapper(value);
1702 * The base implementation of `_.create` without support for assigning
1703 * properties to the created object.
1706 * @param {Object} proto The object to inherit from.
1707 * @returns {Object} Returns the new object.
1709 var baseCreate = (function() {
1710 function object() {}
1711 return function(proto) {
1712 if (!isObject(proto)) {
1716 return objectCreate(proto);
1718 object.prototype = proto;
1719 var result = new object;
1720 object.prototype = undefined;
1726 * The function whose prototype chain sequence wrappers inherit from.
1730 function baseLodash() {
1731 // No operation performed.
1735 * The base constructor for creating `lodash` wrapper objects.
1738 * @param {*} value The value to wrap.
1739 * @param {boolean} [chainAll] Enable explicit method chain sequences.
1741 function LodashWrapper(value, chainAll) {
1742 this.__wrapped__ = value;
1743 this.__actions__ = [];
1744 this.__chain__ = !!chainAll;
1746 this.__values__ = undefined;
1750 * By default, the template delimiters used by lodash are like those in
1751 * embedded Ruby (ERB). Change the following template settings to use
1752 * alternative delimiters.
1758 lodash.templateSettings = {
1761 * Used to detect `data` property values to be HTML-escaped.
1763 * @memberOf _.templateSettings
1769 * Used to detect code to be evaluated.
1771 * @memberOf _.templateSettings
1774 'evaluate': reEvaluate,
1777 * Used to detect `data` property values to inject.
1779 * @memberOf _.templateSettings
1782 'interpolate': reInterpolate,
1785 * Used to reference the data object in the template text.
1787 * @memberOf _.templateSettings
1793 * Used to import variables into the compiled template.
1795 * @memberOf _.templateSettings
1801 * A reference to the `lodash` function.
1803 * @memberOf _.templateSettings.imports
1810 // Ensure wrappers are instances of `baseLodash`.
1811 lodash.prototype = baseLodash.prototype;
1812 lodash.prototype.constructor = lodash;
1814 LodashWrapper.prototype = baseCreate(baseLodash.prototype);
1815 LodashWrapper.prototype.constructor = LodashWrapper;
1817 /*------------------------------------------------------------------------*/
1820 * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
1824 * @param {*} value The value to wrap.
1826 function LazyWrapper(value) {
1827 this.__wrapped__ = value;
1828 this.__actions__ = [];
1830 this.__filtered__ = false;
1831 this.__iteratees__ = [];
1832 this.__takeCount__ = MAX_ARRAY_LENGTH;
1833 this.__views__ = [];
1837 * Creates a clone of the lazy wrapper object.
1841 * @memberOf LazyWrapper
1842 * @returns {Object} Returns the cloned `LazyWrapper` object.
1844 function lazyClone() {
1845 var result = new LazyWrapper(this.__wrapped__);
1846 result.__actions__ = copyArray(this.__actions__);
1847 result.__dir__ = this.__dir__;
1848 result.__filtered__ = this.__filtered__;
1849 result.__iteratees__ = copyArray(this.__iteratees__);
1850 result.__takeCount__ = this.__takeCount__;
1851 result.__views__ = copyArray(this.__views__);
1856 * Reverses the direction of lazy iteration.
1860 * @memberOf LazyWrapper
1861 * @returns {Object} Returns the new reversed `LazyWrapper` object.
1863 function lazyReverse() {
1864 if (this.__filtered__) {
1865 var result = new LazyWrapper(this);
1866 result.__dir__ = -1;
1867 result.__filtered__ = true;
1869 result = this.clone();
1870 result.__dir__ *= -1;
1876 * Extracts the unwrapped value from its lazy wrapper.
1880 * @memberOf LazyWrapper
1881 * @returns {*} Returns the unwrapped value.
1883 function lazyValue() {
1884 var array = this.__wrapped__.value(),
1886 isArr = isArray(array),
1888 arrLength = isArr ? array.length : 0,
1889 view = getView(0, arrLength, this.__views__),
1892 length = end - start,
1893 index = isRight ? end : (start - 1),
1894 iteratees = this.__iteratees__,
1895 iterLength = iteratees.length,
1897 takeCount = nativeMin(length, this.__takeCount__);
1899 if (!isArr || arrLength < LARGE_ARRAY_SIZE ||
1900 (arrLength == length && takeCount == length)) {
1901 return baseWrapperValue(array, this.__actions__);
1906 while (length-- && resIndex < takeCount) {
1910 value = array[index];
1912 while (++iterIndex < iterLength) {
1913 var data = iteratees[iterIndex],
1914 iteratee = data.iteratee,
1916 computed = iteratee(value);
1918 if (type == LAZY_MAP_FLAG) {
1920 } else if (!computed) {
1921 if (type == LAZY_FILTER_FLAG) {
1928 result[resIndex++] = value;
1933 // Ensure `LazyWrapper` is an instance of `baseLodash`.
1934 LazyWrapper.prototype = baseCreate(baseLodash.prototype);
1935 LazyWrapper.prototype.constructor = LazyWrapper;
1937 /*------------------------------------------------------------------------*/
1940 * Creates a hash object.
1944 * @param {Array} [entries] The key-value pairs to cache.
1946 function Hash(entries) {
1948 length = entries == null ? 0 : entries.length;
1951 while (++index < length) {
1952 var entry = entries[index];
1953 this.set(entry[0], entry[1]);
1958 * Removes all key-value entries from the hash.
1964 function hashClear() {
1965 this.__data__ = nativeCreate ? nativeCreate(null) : {};
1970 * Removes `key` and its value from the hash.
1975 * @param {Object} hash The hash to modify.
1976 * @param {string} key The key of the value to remove.
1977 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1979 function hashDelete(key) {
1980 var result = this.has(key) && delete this.__data__[key];
1981 this.size -= result ? 1 : 0;
1986 * Gets the hash value for `key`.
1991 * @param {string} key The key of the value to get.
1992 * @returns {*} Returns the entry value.
1994 function hashGet(key) {
1995 var data = this.__data__;
1997 var result = data[key];
1998 return result === HASH_UNDEFINED ? undefined : result;
2000 return hasOwnProperty.call(data, key) ? data[key] : undefined;
2004 * Checks if a hash value for `key` exists.
2009 * @param {string} key The key of the entry to check.
2010 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2012 function hashHas(key) {
2013 var data = this.__data__;
2014 return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);
2018 * Sets the hash `key` to `value`.
2023 * @param {string} key The key of the value to set.
2024 * @param {*} value The value to set.
2025 * @returns {Object} Returns the hash instance.
2027 function hashSet(key, value) {
2028 var data = this.__data__;
2029 this.size += this.has(key) ? 0 : 1;
2030 data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
2034 // Add methods to `Hash`.
2035 Hash.prototype.clear = hashClear;
2036 Hash.prototype['delete'] = hashDelete;
2037 Hash.prototype.get = hashGet;
2038 Hash.prototype.has = hashHas;
2039 Hash.prototype.set = hashSet;
2041 /*------------------------------------------------------------------------*/
2044 * Creates an list cache object.
2048 * @param {Array} [entries] The key-value pairs to cache.
2050 function ListCache(entries) {
2052 length = entries == null ? 0 : entries.length;
2055 while (++index < length) {
2056 var entry = entries[index];
2057 this.set(entry[0], entry[1]);
2062 * Removes all key-value entries from the list cache.
2066 * @memberOf ListCache
2068 function listCacheClear() {
2074 * Removes `key` and its value from the list cache.
2078 * @memberOf ListCache
2079 * @param {string} key The key of the value to remove.
2080 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2082 function listCacheDelete(key) {
2083 var data = this.__data__,
2084 index = assocIndexOf(data, key);
2089 var lastIndex = data.length - 1;
2090 if (index == lastIndex) {
2093 splice.call(data, index, 1);
2100 * Gets the list cache value for `key`.
2104 * @memberOf ListCache
2105 * @param {string} key The key of the value to get.
2106 * @returns {*} Returns the entry value.
2108 function listCacheGet(key) {
2109 var data = this.__data__,
2110 index = assocIndexOf(data, key);
2112 return index < 0 ? undefined : data[index][1];
2116 * Checks if a list cache value for `key` exists.
2120 * @memberOf ListCache
2121 * @param {string} key The key of the entry to check.
2122 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2124 function listCacheHas(key) {
2125 return assocIndexOf(this.__data__, key) > -1;
2129 * Sets the list cache `key` to `value`.
2133 * @memberOf ListCache
2134 * @param {string} key The key of the value to set.
2135 * @param {*} value The value to set.
2136 * @returns {Object} Returns the list cache instance.
2138 function listCacheSet(key, value) {
2139 var data = this.__data__,
2140 index = assocIndexOf(data, key);
2144 data.push([key, value]);
2146 data[index][1] = value;
2151 // Add methods to `ListCache`.
2152 ListCache.prototype.clear = listCacheClear;
2153 ListCache.prototype['delete'] = listCacheDelete;
2154 ListCache.prototype.get = listCacheGet;
2155 ListCache.prototype.has = listCacheHas;
2156 ListCache.prototype.set = listCacheSet;
2158 /*------------------------------------------------------------------------*/
2161 * Creates a map cache object to store key-value pairs.
2165 * @param {Array} [entries] The key-value pairs to cache.
2167 function MapCache(entries) {
2169 length = entries == null ? 0 : entries.length;
2172 while (++index < length) {
2173 var entry = entries[index];
2174 this.set(entry[0], entry[1]);
2179 * Removes all key-value entries from the map.
2183 * @memberOf MapCache
2185 function mapCacheClear() {
2189 'map': new (Map || ListCache),
2195 * Removes `key` and its value from the map.
2199 * @memberOf MapCache
2200 * @param {string} key The key of the value to remove.
2201 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2203 function mapCacheDelete(key) {
2204 var result = getMapData(this, key)['delete'](key);
2205 this.size -= result ? 1 : 0;
2210 * Gets the map value for `key`.
2214 * @memberOf MapCache
2215 * @param {string} key The key of the value to get.
2216 * @returns {*} Returns the entry value.
2218 function mapCacheGet(key) {
2219 return getMapData(this, key).get(key);
2223 * Checks if a map value for `key` exists.
2227 * @memberOf MapCache
2228 * @param {string} key The key of the entry to check.
2229 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2231 function mapCacheHas(key) {
2232 return getMapData(this, key).has(key);
2236 * Sets the map `key` to `value`.
2240 * @memberOf MapCache
2241 * @param {string} key The key of the value to set.
2242 * @param {*} value The value to set.
2243 * @returns {Object} Returns the map cache instance.
2245 function mapCacheSet(key, value) {
2246 var data = getMapData(this, key),
2249 data.set(key, value);
2250 this.size += data.size == size ? 0 : 1;
2254 // Add methods to `MapCache`.
2255 MapCache.prototype.clear = mapCacheClear;
2256 MapCache.prototype['delete'] = mapCacheDelete;
2257 MapCache.prototype.get = mapCacheGet;
2258 MapCache.prototype.has = mapCacheHas;
2259 MapCache.prototype.set = mapCacheSet;
2261 /*------------------------------------------------------------------------*/
2265 * Creates an array cache object to store unique values.
2269 * @param {Array} [values] The values to cache.
2271 function SetCache(values) {
2273 length = values == null ? 0 : values.length;
2275 this.__data__ = new MapCache;
2276 while (++index < length) {
2277 this.add(values[index]);
2282 * Adds `value` to the array cache.
2286 * @memberOf SetCache
2288 * @param {*} value The value to cache.
2289 * @returns {Object} Returns the cache instance.
2291 function setCacheAdd(value) {
2292 this.__data__.set(value, HASH_UNDEFINED);
2297 * Checks if `value` is in the array cache.
2301 * @memberOf SetCache
2302 * @param {*} value The value to search for.
2303 * @returns {number} Returns `true` if `value` is found, else `false`.
2305 function setCacheHas(value) {
2306 return this.__data__.has(value);
2309 // Add methods to `SetCache`.
2310 SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
2311 SetCache.prototype.has = setCacheHas;
2313 /*------------------------------------------------------------------------*/
2316 * Creates a stack cache object to store key-value pairs.
2320 * @param {Array} [entries] The key-value pairs to cache.
2322 function Stack(entries) {
2323 var data = this.__data__ = new ListCache(entries);
2324 this.size = data.size;
2328 * Removes all key-value entries from the stack.
2334 function stackClear() {
2335 this.__data__ = new ListCache;
2340 * Removes `key` and its value from the stack.
2345 * @param {string} key The key of the value to remove.
2346 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2348 function stackDelete(key) {
2349 var data = this.__data__,
2350 result = data['delete'](key);
2352 this.size = data.size;
2357 * Gets the stack value for `key`.
2362 * @param {string} key The key of the value to get.
2363 * @returns {*} Returns the entry value.
2365 function stackGet(key) {
2366 return this.__data__.get(key);
2370 * Checks if a stack value for `key` exists.
2375 * @param {string} key The key of the entry to check.
2376 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2378 function stackHas(key) {
2379 return this.__data__.has(key);
2383 * Sets the stack `key` to `value`.
2388 * @param {string} key The key of the value to set.
2389 * @param {*} value The value to set.
2390 * @returns {Object} Returns the stack cache instance.
2392 function stackSet(key, value) {
2393 var data = this.__data__;
2394 if (data instanceof ListCache) {
2395 var pairs = data.__data__;
2396 if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
2397 pairs.push([key, value]);
2398 this.size = ++data.size;
2401 data = this.__data__ = new MapCache(pairs);
2403 data.set(key, value);
2404 this.size = data.size;
2408 // Add methods to `Stack`.
2409 Stack.prototype.clear = stackClear;
2410 Stack.prototype['delete'] = stackDelete;
2411 Stack.prototype.get = stackGet;
2412 Stack.prototype.has = stackHas;
2413 Stack.prototype.set = stackSet;
2415 /*------------------------------------------------------------------------*/
2418 * Creates an array of the enumerable property names of the array-like `value`.
2421 * @param {*} value The value to query.
2422 * @param {boolean} inherited Specify returning inherited property names.
2423 * @returns {Array} Returns the array of property names.
2425 function arrayLikeKeys(value, inherited) {
2426 var isArr = isArray(value),
2427 isArg = !isArr && isArguments(value),
2428 isBuff = !isArr && !isArg && isBuffer(value),
2429 isType = !isArr && !isArg && !isBuff && isTypedArray(value),
2430 skipIndexes = isArr || isArg || isBuff || isType,
2431 result = skipIndexes ? baseTimes(value.length, String) : [],
2432 length = result.length;
2434 for (var key in value) {
2435 if ((inherited || hasOwnProperty.call(value, key)) &&
2437 // Safari 9 has enumerable `arguments.length` in strict mode.
2439 // Node.js 0.10 has enumerable non-index properties on buffers.
2440 (isBuff && (key == 'offset' || key == 'parent')) ||
2441 // PhantomJS 2 has enumerable non-index properties on typed arrays.
2442 (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
2443 // Skip index properties.
2444 isIndex(key, length)
2453 * A specialized version of `_.sample` for arrays.
2456 * @param {Array} array The array to sample.
2457 * @returns {*} Returns the random element.
2459 function arraySample(array) {
2460 var length = array.length;
2461 return length ? array[baseRandom(0, length - 1)] : undefined;
2465 * A specialized version of `_.sampleSize` for arrays.
2468 * @param {Array} array The array to sample.
2469 * @param {number} n The number of elements to sample.
2470 * @returns {Array} Returns the random elements.
2472 function arraySampleSize(array, n) {
2473 return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
2477 * A specialized version of `_.shuffle` for arrays.
2480 * @param {Array} array The array to shuffle.
2481 * @returns {Array} Returns the new shuffled array.
2483 function arrayShuffle(array) {
2484 return shuffleSelf(copyArray(array));
2488 * Used by `_.defaults` to customize its `_.assignIn` use.
2491 * @param {*} objValue The destination value.
2492 * @param {*} srcValue The source value.
2493 * @param {string} key The key of the property to assign.
2494 * @param {Object} object The parent object of `objValue`.
2495 * @returns {*} Returns the value to assign.
2497 function assignInDefaults(objValue, srcValue, key, object) {
2498 if (objValue === undefined ||
2499 (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
2506 * This function is like `assignValue` except that it doesn't assign
2507 * `undefined` values.
2510 * @param {Object} object The object to modify.
2511 * @param {string} key The key of the property to assign.
2512 * @param {*} value The value to assign.
2514 function assignMergeValue(object, key, value) {
2515 if ((value !== undefined && !eq(object[key], value)) ||
2516 (value === undefined && !(key in object))) {
2517 baseAssignValue(object, key, value);
2522 * Assigns `value` to `key` of `object` if the existing value is not equivalent
2523 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
2524 * for equality comparisons.
2527 * @param {Object} object The object to modify.
2528 * @param {string} key The key of the property to assign.
2529 * @param {*} value The value to assign.
2531 function assignValue(object, key, value) {
2532 var objValue = object[key];
2533 if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
2534 (value === undefined && !(key in object))) {
2535 baseAssignValue(object, key, value);
2540 * Gets the index at which the `key` is found in `array` of key-value pairs.
2543 * @param {Array} array The array to inspect.
2544 * @param {*} key The key to search for.
2545 * @returns {number} Returns the index of the matched value, else `-1`.
2547 function assocIndexOf(array, key) {
2548 var length = array.length;
2550 if (eq(array[length][0], key)) {
2558 * Aggregates elements of `collection` on `accumulator` with keys transformed
2559 * by `iteratee` and values set by `setter`.
2562 * @param {Array|Object} collection The collection to iterate over.
2563 * @param {Function} setter The function to set `accumulator` values.
2564 * @param {Function} iteratee The iteratee to transform keys.
2565 * @param {Object} accumulator The initial aggregated object.
2566 * @returns {Function} Returns `accumulator`.
2568 function baseAggregator(collection, setter, iteratee, accumulator) {
2569 baseEach(collection, function(value, key, collection) {
2570 setter(accumulator, value, iteratee(value), collection);
2576 * The base implementation of `_.assign` without support for multiple sources
2577 * or `customizer` functions.
2580 * @param {Object} object The destination object.
2581 * @param {Object} source The source object.
2582 * @returns {Object} Returns `object`.
2584 function baseAssign(object, source) {
2585 return object && copyObject(source, keys(source), object);
2589 * The base implementation of `_.assignIn` without support for multiple sources
2590 * or `customizer` functions.
2593 * @param {Object} object The destination object.
2594 * @param {Object} source The source object.
2595 * @returns {Object} Returns `object`.
2597 function baseAssignIn(object, source) {
2598 return object && copyObject(source, keysIn(source), object);
2602 * The base implementation of `assignValue` and `assignMergeValue` without
2606 * @param {Object} object The object to modify.
2607 * @param {string} key The key of the property to assign.
2608 * @param {*} value The value to assign.
2610 function baseAssignValue(object, key, value) {
2611 if (key == '__proto__' && defineProperty) {
2612 defineProperty(object, key, {
2613 'configurable': true,
2619 object[key] = value;
2624 * The base implementation of `_.at` without support for individual paths.
2627 * @param {Object} object The object to iterate over.
2628 * @param {string[]} paths The property paths to pick.
2629 * @returns {Array} Returns the picked elements.
2631 function baseAt(object, paths) {
2633 length = paths.length,
2634 result = Array(length),
2635 skip = object == null;
2637 while (++index < length) {
2638 result[index] = skip ? undefined : get(object, paths[index]);
2644 * The base implementation of `_.clamp` which doesn't coerce arguments.
2647 * @param {number} number The number to clamp.
2648 * @param {number} [lower] The lower bound.
2649 * @param {number} upper The upper bound.
2650 * @returns {number} Returns the clamped number.
2652 function baseClamp(number, lower, upper) {
2653 if (number === number) {
2654 if (upper !== undefined) {
2655 number = number <= upper ? number : upper;
2657 if (lower !== undefined) {
2658 number = number >= lower ? number : lower;
2665 * The base implementation of `_.clone` and `_.cloneDeep` which tracks
2666 * traversed objects.
2669 * @param {*} value The value to clone.
2670 * @param {boolean} bitmask The bitmask flags.
2672 * 2 - Flatten inherited properties
2674 * @param {Function} [customizer] The function to customize cloning.
2675 * @param {string} [key] The key of `value`.
2676 * @param {Object} [object] The parent object of `value`.
2677 * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
2678 * @returns {*} Returns the cloned value.
2680 function baseClone(value, bitmask, customizer, key, object, stack) {
2682 isDeep = bitmask & CLONE_DEEP_FLAG,
2683 isFlat = bitmask & CLONE_FLAT_FLAG,
2684 isFull = bitmask & CLONE_SYMBOLS_FLAG;
2687 result = object ? customizer(value, key, object, stack) : customizer(value);
2689 if (result !== undefined) {
2692 if (!isObject(value)) {
2695 var isArr = isArray(value);
2697 result = initCloneArray(value);
2699 return copyArray(value, result);
2702 var tag = getTag(value),
2703 isFunc = tag == funcTag || tag == genTag;
2705 if (isBuffer(value)) {
2706 return cloneBuffer(value, isDeep);
2708 if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
2709 result = (isFlat || isFunc) ? {} : initCloneObject(value);
2712 ? copySymbolsIn(value, baseAssignIn(result, value))
2713 : copySymbols(value, baseAssign(result, value));
2716 if (!cloneableTags[tag]) {
2717 return object ? value : {};
2719 result = initCloneByTag(value, tag, baseClone, isDeep);
2722 // Check for circular references and return its corresponding clone.
2723 stack || (stack = new Stack);
2724 var stacked = stack.get(value);
2728 stack.set(value, result);
2730 var keysFunc = isFull
2731 ? (isFlat ? getAllKeysIn : getAllKeys)
2732 : (isFlat ? keysIn : keys);
2734 var props = isArr ? undefined : keysFunc(value);
2735 arrayEach(props || value, function(subValue, key) {
2738 subValue = value[key];
2740 // Recursively populate clone (susceptible to call stack limits).
2741 assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
2747 * The base implementation of `_.conforms` which doesn't clone `source`.
2750 * @param {Object} source The object of property predicates to conform to.
2751 * @returns {Function} Returns the new spec function.
2753 function baseConforms(source) {
2754 var props = keys(source);
2755 return function(object) {
2756 return baseConformsTo(object, source, props);
2761 * The base implementation of `_.conformsTo` which accepts `props` to check.
2764 * @param {Object} object The object to inspect.
2765 * @param {Object} source The object of property predicates to conform to.
2766 * @returns {boolean} Returns `true` if `object` conforms, else `false`.
2768 function baseConformsTo(object, source, props) {
2769 var length = props.length;
2770 if (object == null) {
2773 object = Object(object);
2775 var key = props[length],
2776 predicate = source[key],
2777 value = object[key];
2779 if ((value === undefined && !(key in object)) || !predicate(value)) {
2787 * The base implementation of `_.delay` and `_.defer` which accepts `args`
2788 * to provide to `func`.
2791 * @param {Function} func The function to delay.
2792 * @param {number} wait The number of milliseconds to delay invocation.
2793 * @param {Array} args The arguments to provide to `func`.
2794 * @returns {number|Object} Returns the timer id or timeout object.
2796 function baseDelay(func, wait, args) {
2797 if (typeof func != 'function') {
2798 throw new TypeError(FUNC_ERROR_TEXT);
2800 return setTimeout(function() { func.apply(undefined, args); }, wait);
2804 * The base implementation of methods like `_.difference` without support
2805 * for excluding multiple arrays or iteratee shorthands.
2808 * @param {Array} array The array to inspect.
2809 * @param {Array} values The values to exclude.
2810 * @param {Function} [iteratee] The iteratee invoked per element.
2811 * @param {Function} [comparator] The comparator invoked per element.
2812 * @returns {Array} Returns the new array of filtered values.
2814 function baseDifference(array, values, iteratee, comparator) {
2816 includes = arrayIncludes,
2818 length = array.length,
2820 valuesLength = values.length;
2826 values = arrayMap(values, baseUnary(iteratee));
2829 includes = arrayIncludesWith;
2832 else if (values.length >= LARGE_ARRAY_SIZE) {
2833 includes = cacheHas;
2835 values = new SetCache(values);
2838 while (++index < length) {
2839 var value = array[index],
2840 computed = iteratee == null ? value : iteratee(value);
2842 value = (comparator || value !== 0) ? value : 0;
2843 if (isCommon && computed === computed) {
2844 var valuesIndex = valuesLength;
2845 while (valuesIndex--) {
2846 if (values[valuesIndex] === computed) {
2852 else if (!includes(values, computed, comparator)) {
2860 * The base implementation of `_.forEach` without support for iteratee shorthands.
2863 * @param {Array|Object} collection The collection to iterate over.
2864 * @param {Function} iteratee The function invoked per iteration.
2865 * @returns {Array|Object} Returns `collection`.
2867 var baseEach = createBaseEach(baseForOwn);
2870 * The base implementation of `_.forEachRight` without support for iteratee shorthands.
2873 * @param {Array|Object} collection The collection to iterate over.
2874 * @param {Function} iteratee The function invoked per iteration.
2875 * @returns {Array|Object} Returns `collection`.
2877 var baseEachRight = createBaseEach(baseForOwnRight, true);
2880 * The base implementation of `_.every` without support for iteratee shorthands.
2883 * @param {Array|Object} collection The collection to iterate over.
2884 * @param {Function} predicate The function invoked per iteration.
2885 * @returns {boolean} Returns `true` if all elements pass the predicate check,
2888 function baseEvery(collection, predicate) {
2890 baseEach(collection, function(value, index, collection) {
2891 result = !!predicate(value, index, collection);
2898 * The base implementation of methods like `_.max` and `_.min` which accepts a
2899 * `comparator` to determine the extremum value.
2902 * @param {Array} array The array to iterate over.
2903 * @param {Function} iteratee The iteratee invoked per iteration.
2904 * @param {Function} comparator The comparator used to compare values.
2905 * @returns {*} Returns the extremum value.
2907 function baseExtremum(array, iteratee, comparator) {
2909 length = array.length;
2911 while (++index < length) {
2912 var value = array[index],
2913 current = iteratee(value);
2915 if (current != null && (computed === undefined
2916 ? (current === current && !isSymbol(current))
2917 : comparator(current, computed)
2919 var computed = current,
2927 * The base implementation of `_.fill` without an iteratee call guard.
2930 * @param {Array} array The array to fill.
2931 * @param {*} value The value to fill `array` with.
2932 * @param {number} [start=0] The start position.
2933 * @param {number} [end=array.length] The end position.
2934 * @returns {Array} Returns `array`.
2936 function baseFill(array, value, start, end) {
2937 var length = array.length;
2939 start = toInteger(start);
2941 start = -start > length ? 0 : (length + start);
2943 end = (end === undefined || end > length) ? length : toInteger(end);
2947 end = start > end ? 0 : toLength(end);
2948 while (start < end) {
2949 array[start++] = value;
2955 * The base implementation of `_.filter` without support for iteratee shorthands.
2958 * @param {Array|Object} collection The collection to iterate over.
2959 * @param {Function} predicate The function invoked per iteration.
2960 * @returns {Array} Returns the new filtered array.
2962 function baseFilter(collection, predicate) {
2964 baseEach(collection, function(value, index, collection) {
2965 if (predicate(value, index, collection)) {
2973 * The base implementation of `_.flatten` with support for restricting flattening.
2976 * @param {Array} array The array to flatten.
2977 * @param {number} depth The maximum recursion depth.
2978 * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
2979 * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
2980 * @param {Array} [result=[]] The initial result value.
2981 * @returns {Array} Returns the new flattened array.
2983 function baseFlatten(array, depth, predicate, isStrict, result) {
2985 length = array.length;
2987 predicate || (predicate = isFlattenable);
2988 result || (result = []);
2990 while (++index < length) {
2991 var value = array[index];
2992 if (depth > 0 && predicate(value)) {
2994 // Recursively flatten arrays (susceptible to call stack limits).
2995 baseFlatten(value, depth - 1, predicate, isStrict, result);
2997 arrayPush(result, value);
2999 } else if (!isStrict) {
3000 result[result.length] = value;
3007 * The base implementation of `baseForOwn` which iterates over `object`
3008 * properties returned by `keysFunc` and invokes `iteratee` for each property.
3009 * Iteratee functions may exit iteration early by explicitly returning `false`.
3012 * @param {Object} object The object to iterate over.
3013 * @param {Function} iteratee The function invoked per iteration.
3014 * @param {Function} keysFunc The function to get the keys of `object`.
3015 * @returns {Object} Returns `object`.
3017 var baseFor = createBaseFor();
3020 * This function is like `baseFor` except that it iterates over properties
3021 * in the opposite order.
3024 * @param {Object} object The object to iterate over.
3025 * @param {Function} iteratee The function invoked per iteration.
3026 * @param {Function} keysFunc The function to get the keys of `object`.
3027 * @returns {Object} Returns `object`.
3029 var baseForRight = createBaseFor(true);
3032 * The base implementation of `_.forOwn` without support for iteratee shorthands.
3035 * @param {Object} object The object to iterate over.
3036 * @param {Function} iteratee The function invoked per iteration.
3037 * @returns {Object} Returns `object`.
3039 function baseForOwn(object, iteratee) {
3040 return object && baseFor(object, iteratee, keys);
3044 * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
3047 * @param {Object} object The object to iterate over.
3048 * @param {Function} iteratee The function invoked per iteration.
3049 * @returns {Object} Returns `object`.
3051 function baseForOwnRight(object, iteratee) {
3052 return object && baseForRight(object, iteratee, keys);
3056 * The base implementation of `_.functions` which creates an array of
3057 * `object` function property names filtered from `props`.
3060 * @param {Object} object The object to inspect.
3061 * @param {Array} props The property names to filter.
3062 * @returns {Array} Returns the function names.
3064 function baseFunctions(object, props) {
3065 return arrayFilter(props, function(key) {
3066 return isFunction(object[key]);
3071 * The base implementation of `_.get` without support for default values.
3074 * @param {Object} object The object to query.
3075 * @param {Array|string} path The path of the property to get.
3076 * @returns {*} Returns the resolved value.
3078 function baseGet(object, path) {
3079 path = castPath(path, object);
3082 length = path.length;
3084 while (object != null && index < length) {
3085 object = object[toKey(path[index++])];
3087 return (index && index == length) ? object : undefined;
3091 * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
3092 * `keysFunc` and `symbolsFunc` to get the enumerable property names and
3093 * symbols of `object`.
3096 * @param {Object} object The object to query.
3097 * @param {Function} keysFunc The function to get the keys of `object`.
3098 * @param {Function} symbolsFunc The function to get the symbols of `object`.
3099 * @returns {Array} Returns the array of property names and symbols.
3101 function baseGetAllKeys(object, keysFunc, symbolsFunc) {
3102 var result = keysFunc(object);
3103 return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
3107 * The base implementation of `getTag` without fallbacks for buggy environments.
3110 * @param {*} value The value to query.
3111 * @returns {string} Returns the `toStringTag`.
3113 function baseGetTag(value) {
3114 if (value == null) {
3115 return value === undefined ? undefinedTag : nullTag;
3117 value = Object(value);
3118 return (symToStringTag && symToStringTag in value)
3120 : objectToString(value);
3124 * The base implementation of `_.gt` which doesn't coerce arguments.
3127 * @param {*} value The value to compare.
3128 * @param {*} other The other value to compare.
3129 * @returns {boolean} Returns `true` if `value` is greater than `other`,
3132 function baseGt(value, other) {
3133 return value > other;
3137 * The base implementation of `_.has` without support for deep paths.
3140 * @param {Object} [object] The object to query.
3141 * @param {Array|string} key The key to check.
3142 * @returns {boolean} Returns `true` if `key` exists, else `false`.
3144 function baseHas(object, key) {
3145 return object != null && hasOwnProperty.call(object, key);
3149 * The base implementation of `_.hasIn` without support for deep paths.
3152 * @param {Object} [object] The object to query.
3153 * @param {Array|string} key The key to check.
3154 * @returns {boolean} Returns `true` if `key` exists, else `false`.
3156 function baseHasIn(object, key) {
3157 return object != null && key in Object(object);
3161 * The base implementation of `_.inRange` which doesn't coerce arguments.
3164 * @param {number} number The number to check.
3165 * @param {number} start The start of the range.
3166 * @param {number} end The end of the range.
3167 * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
3169 function baseInRange(number, start, end) {
3170 return number >= nativeMin(start, end) && number < nativeMax(start, end);
3174 * The base implementation of methods like `_.intersection`, without support
3175 * for iteratee shorthands, that accepts an array of arrays to inspect.
3178 * @param {Array} arrays The arrays to inspect.
3179 * @param {Function} [iteratee] The iteratee invoked per element.
3180 * @param {Function} [comparator] The comparator invoked per element.
3181 * @returns {Array} Returns the new array of shared values.
3183 function baseIntersection(arrays, iteratee, comparator) {
3184 var includes = comparator ? arrayIncludesWith : arrayIncludes,
3185 length = arrays[0].length,
3186 othLength = arrays.length,
3187 othIndex = othLength,
3188 caches = Array(othLength),
3189 maxLength = Infinity,
3192 while (othIndex--) {
3193 var array = arrays[othIndex];
3194 if (othIndex && iteratee) {
3195 array = arrayMap(array, baseUnary(iteratee));
3197 maxLength = nativeMin(array.length, maxLength);
3198 caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
3199 ? new SetCache(othIndex && array)
3208 while (++index < length && result.length < maxLength) {
3209 var value = array[index],
3210 computed = iteratee ? iteratee(value) : value;
3212 value = (comparator || value !== 0) ? value : 0;
3214 ? cacheHas(seen, computed)
3215 : includes(result, computed, comparator)
3217 othIndex = othLength;
3218 while (--othIndex) {
3219 var cache = caches[othIndex];
3221 ? cacheHas(cache, computed)
3222 : includes(arrays[othIndex], computed, comparator))
3228 seen.push(computed);
3237 * The base implementation of `_.invert` and `_.invertBy` which inverts
3238 * `object` with values transformed by `iteratee` and set by `setter`.
3241 * @param {Object} object The object to iterate over.
3242 * @param {Function} setter The function to set `accumulator` values.
3243 * @param {Function} iteratee The iteratee to transform values.
3244 * @param {Object} accumulator The initial inverted object.
3245 * @returns {Function} Returns `accumulator`.
3247 function baseInverter(object, setter, iteratee, accumulator) {
3248 baseForOwn(object, function(value, key, object) {
3249 setter(accumulator, iteratee(value), key, object);
3255 * The base implementation of `_.invoke` without support for individual
3259 * @param {Object} object The object to query.
3260 * @param {Array|string} path The path of the method to invoke.
3261 * @param {Array} args The arguments to invoke the method with.
3262 * @returns {*} Returns the result of the invoked method.
3264 function baseInvoke(object, path, args) {
3265 path = castPath(path, object);
3266 object = parent(object, path);
3267 var func = object == null ? object : object[toKey(last(path))];
3268 return func == null ? undefined : apply(func, object, args);
3272 * The base implementation of `_.isArguments`.
3275 * @param {*} value The value to check.
3276 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
3278 function baseIsArguments(value) {
3279 return isObjectLike(value) && baseGetTag(value) == argsTag;
3283 * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
3286 * @param {*} value The value to check.
3287 * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
3289 function baseIsArrayBuffer(value) {
3290 return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
3294 * The base implementation of `_.isDate` without Node.js optimizations.
3297 * @param {*} value The value to check.
3298 * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
3300 function baseIsDate(value) {
3301 return isObjectLike(value) && baseGetTag(value) == dateTag;
3305 * The base implementation of `_.isEqual` which supports partial comparisons
3306 * and tracks traversed objects.
3309 * @param {*} value The value to compare.
3310 * @param {*} other The other value to compare.
3311 * @param {boolean} bitmask The bitmask flags.
3312 * 1 - Unordered comparison
3313 * 2 - Partial comparison
3314 * @param {Function} [customizer] The function to customize comparisons.
3315 * @param {Object} [stack] Tracks traversed `value` and `other` objects.
3316 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
3318 function baseIsEqual(value, other, bitmask, customizer, stack) {
3319 if (value === other) {
3322 if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
3323 return value !== value && other !== other;
3325 return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
3329 * A specialized version of `baseIsEqual` for arrays and objects which performs
3330 * deep comparisons and tracks traversed objects enabling objects with circular
3331 * references to be compared.
3334 * @param {Object} object The object to compare.
3335 * @param {Object} other The other object to compare.
3336 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
3337 * @param {Function} customizer The function to customize comparisons.
3338 * @param {Function} equalFunc The function to determine equivalents of values.
3339 * @param {Object} [stack] Tracks traversed `object` and `other` objects.
3340 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
3342 function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
3343 var objIsArr = isArray(object),
3344 othIsArr = isArray(other),
3349 objTag = getTag(object);
3350 objTag = objTag == argsTag ? objectTag : objTag;
3353 othTag = getTag(other);
3354 othTag = othTag == argsTag ? objectTag : othTag;
3356 var objIsObj = objTag == objectTag,
3357 othIsObj = othTag == objectTag,
3358 isSameTag = objTag == othTag;
3360 if (isSameTag && isBuffer(object)) {
3361 if (!isBuffer(other)) {
3367 if (isSameTag && !objIsObj) {
3368 stack || (stack = new Stack);
3369 return (objIsArr || isTypedArray(object))
3370 ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
3371 : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
3373 if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
3374 var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
3375 othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
3377 if (objIsWrapped || othIsWrapped) {
3378 var objUnwrapped = objIsWrapped ? object.value() : object,
3379 othUnwrapped = othIsWrapped ? other.value() : other;
3381 stack || (stack = new Stack);
3382 return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
3388 stack || (stack = new Stack);
3389 return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
3393 * The base implementation of `_.isMap` without Node.js optimizations.
3396 * @param {*} value The value to check.
3397 * @returns {boolean} Returns `true` if `value` is a map, else `false`.
3399 function baseIsMap(value) {
3400 return isObjectLike(value) && getTag(value) == mapTag;
3404 * The base implementation of `_.isMatch` without support for iteratee shorthands.
3407 * @param {Object} object The object to inspect.
3408 * @param {Object} source The object of property values to match.
3409 * @param {Array} matchData The property names, values, and compare flags to match.
3410 * @param {Function} [customizer] The function to customize comparisons.
3411 * @returns {boolean} Returns `true` if `object` is a match, else `false`.
3413 function baseIsMatch(object, source, matchData, customizer) {
3414 var index = matchData.length,
3416 noCustomizer = !customizer;
3418 if (object == null) {
3421 object = Object(object);
3423 var data = matchData[index];
3424 if ((noCustomizer && data[2])
3425 ? data[1] !== object[data[0]]
3426 : !(data[0] in object)
3431 while (++index < length) {
3432 data = matchData[index];
3434 objValue = object[key],
3437 if (noCustomizer && data[2]) {
3438 if (objValue === undefined && !(key in object)) {
3442 var stack = new Stack;
3444 var result = customizer(objValue, srcValue, key, object, source, stack);
3446 if (!(result === undefined
3447 ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
3458 * The base implementation of `_.isNative` without bad shim checks.
3461 * @param {*} value The value to check.
3462 * @returns {boolean} Returns `true` if `value` is a native function,
3465 function baseIsNative(value) {
3466 if (!isObject(value) || isMasked(value)) {
3469 var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
3470 return pattern.test(toSource(value));
3474 * The base implementation of `_.isRegExp` without Node.js optimizations.
3477 * @param {*} value The value to check.
3478 * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
3480 function baseIsRegExp(value) {
3481 return isObjectLike(value) && baseGetTag(value) == regexpTag;
3485 * The base implementation of `_.isSet` without Node.js optimizations.
3488 * @param {*} value The value to check.
3489 * @returns {boolean} Returns `true` if `value` is a set, else `false`.
3491 function baseIsSet(value) {
3492 return isObjectLike(value) && getTag(value) == setTag;
3496 * The base implementation of `_.isTypedArray` without Node.js optimizations.
3499 * @param {*} value The value to check.
3500 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
3502 function baseIsTypedArray(value) {
3503 return isObjectLike(value) &&
3504 isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
3508 * The base implementation of `_.iteratee`.
3511 * @param {*} [value=_.identity] The value to convert to an iteratee.
3512 * @returns {Function} Returns the iteratee.
3514 function baseIteratee(value) {
3515 // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
3516 // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
3517 if (typeof value == 'function') {
3520 if (value == null) {
3523 if (typeof value == 'object') {
3524 return isArray(value)
3525 ? baseMatchesProperty(value[0], value[1])
3526 : baseMatches(value);
3528 return property(value);
3532 * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
3535 * @param {Object} object The object to query.
3536 * @returns {Array} Returns the array of property names.
3538 function baseKeys(object) {
3539 if (!isPrototype(object)) {
3540 return nativeKeys(object);
3543 for (var key in Object(object)) {
3544 if (hasOwnProperty.call(object, key) && key != 'constructor') {
3552 * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
3555 * @param {Object} object The object to query.
3556 * @returns {Array} Returns the array of property names.
3558 function baseKeysIn(object) {
3559 if (!isObject(object)) {
3560 return nativeKeysIn(object);
3562 var isProto = isPrototype(object),
3565 for (var key in object) {
3566 if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
3574 * The base implementation of `_.lt` which doesn't coerce arguments.
3577 * @param {*} value The value to compare.
3578 * @param {*} other The other value to compare.
3579 * @returns {boolean} Returns `true` if `value` is less than `other`,
3582 function baseLt(value, other) {
3583 return value < other;
3587 * The base implementation of `_.map` without support for iteratee shorthands.
3590 * @param {Array|Object} collection The collection to iterate over.
3591 * @param {Function} iteratee The function invoked per iteration.
3592 * @returns {Array} Returns the new mapped array.
3594 function baseMap(collection, iteratee) {
3596 result = isArrayLike(collection) ? Array(collection.length) : [];
3598 baseEach(collection, function(value, key, collection) {
3599 result[++index] = iteratee(value, key, collection);
3605 * The base implementation of `_.matches` which doesn't clone `source`.
3608 * @param {Object} source The object of property values to match.
3609 * @returns {Function} Returns the new spec function.
3611 function baseMatches(source) {
3612 var matchData = getMatchData(source);
3613 if (matchData.length == 1 && matchData[0][2]) {
3614 return matchesStrictComparable(matchData[0][0], matchData[0][1]);
3616 return function(object) {
3617 return object === source || baseIsMatch(object, source, matchData);
3622 * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
3625 * @param {string} path The path of the property to get.
3626 * @param {*} srcValue The value to match.
3627 * @returns {Function} Returns the new spec function.
3629 function baseMatchesProperty(path, srcValue) {
3630 if (isKey(path) && isStrictComparable(srcValue)) {
3631 return matchesStrictComparable(toKey(path), srcValue);
3633 return function(object) {
3634 var objValue = get(object, path);
3635 return (objValue === undefined && objValue === srcValue)
3636 ? hasIn(object, path)
3637 : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
3642 * The base implementation of `_.merge` without support for multiple sources.
3645 * @param {Object} object The destination object.
3646 * @param {Object} source The source object.
3647 * @param {number} srcIndex The index of `source`.
3648 * @param {Function} [customizer] The function to customize merged values.
3649 * @param {Object} [stack] Tracks traversed source values and their merged
3652 function baseMerge(object, source, srcIndex, customizer, stack) {
3653 if (object === source) {
3656 baseFor(source, function(srcValue, key) {
3657 if (isObject(srcValue)) {
3658 stack || (stack = new Stack);
3659 baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
3662 var newValue = customizer
3663 ? customizer(object[key], srcValue, (key + ''), object, source, stack)
3666 if (newValue === undefined) {
3667 newValue = srcValue;
3669 assignMergeValue(object, key, newValue);
3675 * A specialized version of `baseMerge` for arrays and objects which performs
3676 * deep merges and tracks traversed objects enabling objects with circular
3677 * references to be merged.
3680 * @param {Object} object The destination object.
3681 * @param {Object} source The source object.
3682 * @param {string} key The key of the value to merge.
3683 * @param {number} srcIndex The index of `source`.
3684 * @param {Function} mergeFunc The function to merge values.
3685 * @param {Function} [customizer] The function to customize assigned values.
3686 * @param {Object} [stack] Tracks traversed source values and their merged
3689 function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
3690 var objValue = object[key],
3691 srcValue = source[key],
3692 stacked = stack.get(srcValue);
3695 assignMergeValue(object, key, stacked);
3698 var newValue = customizer
3699 ? customizer(objValue, srcValue, (key + ''), object, source, stack)
3702 var isCommon = newValue === undefined;
3705 var isArr = isArray(srcValue),
3706 isBuff = !isArr && isBuffer(srcValue),
3707 isTyped = !isArr && !isBuff && isTypedArray(srcValue);
3709 newValue = srcValue;
3710 if (isArr || isBuff || isTyped) {
3711 if (isArray(objValue)) {
3712 newValue = objValue;
3714 else if (isArrayLikeObject(objValue)) {
3715 newValue = copyArray(objValue);
3719 newValue = cloneBuffer(srcValue, true);
3723 newValue = cloneTypedArray(srcValue, true);
3729 else if (isPlainObject(srcValue) || isArguments(srcValue)) {
3730 newValue = objValue;
3731 if (isArguments(objValue)) {
3732 newValue = toPlainObject(objValue);
3734 else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
3735 newValue = initCloneObject(srcValue);
3743 // Recursively merge objects and arrays (susceptible to call stack limits).
3744 stack.set(srcValue, newValue);
3745 mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
3746 stack['delete'](srcValue);
3748 assignMergeValue(object, key, newValue);
3752 * The base implementation of `_.nth` which doesn't coerce arguments.
3755 * @param {Array} array The array to query.
3756 * @param {number} n The index of the element to return.
3757 * @returns {*} Returns the nth element of `array`.
3759 function baseNth(array, n) {
3760 var length = array.length;
3764 n += n < 0 ? length : 0;
3765 return isIndex(n, length) ? array[n] : undefined;
3769 * The base implementation of `_.orderBy` without param guards.
3772 * @param {Array|Object} collection The collection to iterate over.
3773 * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
3774 * @param {string[]} orders The sort orders of `iteratees`.
3775 * @returns {Array} Returns the new sorted array.
3777 function baseOrderBy(collection, iteratees, orders) {
3779 iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));
3781 var result = baseMap(collection, function(value, key, collection) {
3782 var criteria = arrayMap(iteratees, function(iteratee) {
3783 return iteratee(value);
3785 return { 'criteria': criteria, 'index': ++index, 'value': value };
3788 return baseSortBy(result, function(object, other) {
3789 return compareMultiple(object, other, orders);
3794 * The base implementation of `_.pick` without support for individual
3795 * property identifiers.
3798 * @param {Object} object The source object.
3799 * @param {string[]} paths The property paths to pick.
3800 * @returns {Object} Returns the new object.
3802 function basePick(object, paths) {
3803 object = Object(object);
3804 return basePickBy(object, paths, function(value, path) {
3805 return hasIn(object, path);
3810 * The base implementation of `_.pickBy` without support for iteratee shorthands.
3813 * @param {Object} object The source object.
3814 * @param {string[]} paths The property paths to pick.
3815 * @param {Function} predicate The function invoked per property.
3816 * @returns {Object} Returns the new object.
3818 function basePickBy(object, paths, predicate) {
3820 length = paths.length,
3823 while (++index < length) {
3824 var path = paths[index],
3825 value = baseGet(object, path);
3827 if (predicate(value, path)) {
3828 baseSet(result, path, value);
3835 * A specialized version of `baseProperty` which supports deep paths.
3838 * @param {Array|string} path The path of the property to get.
3839 * @returns {Function} Returns the new accessor function.
3841 function basePropertyDeep(path) {
3842 return function(object) {
3843 return baseGet(object, path);
3848 * The base implementation of `_.pullAllBy` without support for iteratee
3852 * @param {Array} array The array to modify.
3853 * @param {Array} values The values to remove.
3854 * @param {Function} [iteratee] The iteratee invoked per element.
3855 * @param {Function} [comparator] The comparator invoked per element.
3856 * @returns {Array} Returns `array`.
3858 function basePullAll(array, values, iteratee, comparator) {
3859 var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
3861 length = values.length,
3864 if (array === values) {
3865 values = copyArray(values);
3868 seen = arrayMap(array, baseUnary(iteratee));
3870 while (++index < length) {
3872 value = values[index],
3873 computed = iteratee ? iteratee(value) : value;
3875 while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
3876 if (seen !== array) {
3877 splice.call(seen, fromIndex, 1);
3879 splice.call(array, fromIndex, 1);
3886 * The base implementation of `_.pullAt` without support for individual
3887 * indexes or capturing the removed elements.
3890 * @param {Array} array The array to modify.
3891 * @param {number[]} indexes The indexes of elements to remove.
3892 * @returns {Array} Returns `array`.
3894 function basePullAt(array, indexes) {
3895 var length = array ? indexes.length : 0,
3896 lastIndex = length - 1;
3899 var index = indexes[length];
3900 if (length == lastIndex || index !== previous) {
3901 var previous = index;
3902 if (isIndex(index)) {
3903 splice.call(array, index, 1);
3906 var path = castPath(index, array),
3907 object = parent(array, path);
3909 if (object != null) {
3910 delete object[toKey(last(path))];
3919 * The base implementation of `_.random` without support for returning
3920 * floating-point numbers.
3923 * @param {number} lower The lower bound.
3924 * @param {number} upper The upper bound.
3925 * @returns {number} Returns the random number.
3927 function baseRandom(lower, upper) {
3928 return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
3932 * The base implementation of `_.range` and `_.rangeRight` which doesn't
3936 * @param {number} start The start of the range.
3937 * @param {number} end The end of the range.
3938 * @param {number} step The value to increment or decrement by.
3939 * @param {boolean} [fromRight] Specify iterating from right to left.
3940 * @returns {Array} Returns the range of numbers.
3942 function baseRange(start, end, step, fromRight) {
3944 length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
3945 result = Array(length);
3948 result[fromRight ? length : ++index] = start;
3955 * The base implementation of `_.repeat` which doesn't coerce arguments.
3958 * @param {string} string The string to repeat.
3959 * @param {number} n The number of times to repeat the string.
3960 * @returns {string} Returns the repeated string.
3962 function baseRepeat(string, n) {
3964 if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
3967 // Leverage the exponentiation by squaring algorithm for a faster repeat.
3968 // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
3973 n = nativeFloor(n / 2);
3983 * The base implementation of `_.rest` which doesn't validate or coerce arguments.
3986 * @param {Function} func The function to apply a rest parameter to.
3987 * @param {number} [start=func.length-1] The start position of the rest parameter.
3988 * @returns {Function} Returns the new function.
3990 function baseRest(func, start) {
3991 return setToString(overRest(func, start, identity), func + '');
3995 * The base implementation of `_.sample`.
3998 * @param {Array|Object} collection The collection to sample.
3999 * @returns {*} Returns the random element.
4001 function baseSample(collection) {
4002 return arraySample(values(collection));
4006 * The base implementation of `_.sampleSize` without param guards.
4009 * @param {Array|Object} collection The collection to sample.
4010 * @param {number} n The number of elements to sample.
4011 * @returns {Array} Returns the random elements.
4013 function baseSampleSize(collection, n) {
4014 var array = values(collection);
4015 return shuffleSelf(array, baseClamp(n, 0, array.length));
4019 * The base implementation of `_.set`.
4022 * @param {Object} object The object to modify.
4023 * @param {Array|string} path The path of the property to set.
4024 * @param {*} value The value to set.
4025 * @param {Function} [customizer] The function to customize path creation.
4026 * @returns {Object} Returns `object`.
4028 function baseSet(object, path, value, customizer) {
4029 if (!isObject(object)) {
4032 path = castPath(path, object);
4035 length = path.length,
4036 lastIndex = length - 1,
4039 while (nested != null && ++index < length) {
4040 var key = toKey(path[index]),
4043 if (index != lastIndex) {
4044 var objValue = nested[key];
4045 newValue = customizer ? customizer(objValue, key, nested) : undefined;
4046 if (newValue === undefined) {
4047 newValue = isObject(objValue)
4049 : (isIndex(path[index + 1]) ? [] : {});
4052 assignValue(nested, key, newValue);
4053 nested = nested[key];
4059 * The base implementation of `setData` without support for hot loop shorting.
4062 * @param {Function} func The function to associate metadata with.
4063 * @param {*} data The metadata.
4064 * @returns {Function} Returns `func`.
4066 var baseSetData = !metaMap ? identity : function(func, data) {
4067 metaMap.set(func, data);
4072 * The base implementation of `setToString` without support for hot loop shorting.
4075 * @param {Function} func The function to modify.
4076 * @param {Function} string The `toString` result.
4077 * @returns {Function} Returns `func`.
4079 var baseSetToString = !defineProperty ? identity : function(func, string) {
4080 return defineProperty(func, 'toString', {
4081 'configurable': true,
4082 'enumerable': false,
4083 'value': constant(string),
4089 * The base implementation of `_.shuffle`.
4092 * @param {Array|Object} collection The collection to shuffle.
4093 * @returns {Array} Returns the new shuffled array.
4095 function baseShuffle(collection) {
4096 return shuffleSelf(values(collection));
4100 * The base implementation of `_.slice` without an iteratee call guard.
4103 * @param {Array} array The array to slice.
4104 * @param {number} [start=0] The start position.
4105 * @param {number} [end=array.length] The end position.
4106 * @returns {Array} Returns the slice of `array`.
4108 function baseSlice(array, start, end) {
4110 length = array.length;
4113 start = -start > length ? 0 : (length + start);
4115 end = end > length ? length : end;
4119 length = start > end ? 0 : ((end - start) >>> 0);
4122 var result = Array(length);
4123 while (++index < length) {
4124 result[index] = array[index + start];
4130 * The base implementation of `_.some` without support for iteratee shorthands.
4133 * @param {Array|Object} collection The collection to iterate over.
4134 * @param {Function} predicate The function invoked per iteration.
4135 * @returns {boolean} Returns `true` if any element passes the predicate check,
4138 function baseSome(collection, predicate) {
4141 baseEach(collection, function(value, index, collection) {
4142 result = predicate(value, index, collection);
4149 * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
4150 * performs a binary search of `array` to determine the index at which `value`
4151 * should be inserted into `array` in order to maintain its sort order.
4154 * @param {Array} array The sorted array to inspect.
4155 * @param {*} value The value to evaluate.
4156 * @param {boolean} [retHighest] Specify returning the highest qualified index.
4157 * @returns {number} Returns the index at which `value` should be inserted
4160 function baseSortedIndex(array, value, retHighest) {
4162 high = array == null ? low : array.length;
4164 if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
4165 while (low < high) {
4166 var mid = (low + high) >>> 1,
4167 computed = array[mid];
4169 if (computed !== null && !isSymbol(computed) &&
4170 (retHighest ? (computed <= value) : (computed < value))) {
4178 return baseSortedIndexBy(array, value, identity, retHighest);
4182 * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
4183 * which invokes `iteratee` for `value` and each element of `array` to compute
4184 * their sort ranking. The iteratee is invoked with one argument; (value).
4187 * @param {Array} array The sorted array to inspect.
4188 * @param {*} value The value to evaluate.
4189 * @param {Function} iteratee The iteratee invoked per element.
4190 * @param {boolean} [retHighest] Specify returning the highest qualified index.
4191 * @returns {number} Returns the index at which `value` should be inserted
4194 function baseSortedIndexBy(array, value, iteratee, retHighest) {
4195 value = iteratee(value);
4198 high = array == null ? 0 : array.length,
4199 valIsNaN = value !== value,
4200 valIsNull = value === null,
4201 valIsSymbol = isSymbol(value),
4202 valIsUndefined = value === undefined;
4204 while (low < high) {
4205 var mid = nativeFloor((low + high) / 2),
4206 computed = iteratee(array[mid]),
4207 othIsDefined = computed !== undefined,
4208 othIsNull = computed === null,
4209 othIsReflexive = computed === computed,
4210 othIsSymbol = isSymbol(computed);
4213 var setLow = retHighest || othIsReflexive;
4214 } else if (valIsUndefined) {
4215 setLow = othIsReflexive && (retHighest || othIsDefined);
4216 } else if (valIsNull) {
4217 setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
4218 } else if (valIsSymbol) {
4219 setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
4220 } else if (othIsNull || othIsSymbol) {
4223 setLow = retHighest ? (computed <= value) : (computed < value);
4231 return nativeMin(high, MAX_ARRAY_INDEX);
4235 * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
4236 * support for iteratee shorthands.
4239 * @param {Array} array The array to inspect.
4240 * @param {Function} [iteratee] The iteratee invoked per element.
4241 * @returns {Array} Returns the new duplicate free array.
4243 function baseSortedUniq(array, iteratee) {
4245 length = array.length,
4249 while (++index < length) {
4250 var value = array[index],
4251 computed = iteratee ? iteratee(value) : value;
4253 if (!index || !eq(computed, seen)) {
4254 var seen = computed;
4255 result[resIndex++] = value === 0 ? 0 : value;
4262 * The base implementation of `_.toNumber` which doesn't ensure correct
4263 * conversions of binary, hexadecimal, or octal string values.
4266 * @param {*} value The value to process.
4267 * @returns {number} Returns the number.
4269 function baseToNumber(value) {
4270 if (typeof value == 'number') {
4273 if (isSymbol(value)) {
4280 * The base implementation of `_.toString` which doesn't convert nullish
4281 * values to empty strings.
4284 * @param {*} value The value to process.
4285 * @returns {string} Returns the string.
4287 function baseToString(value) {
4288 // Exit early for strings to avoid a performance hit in some environments.
4289 if (typeof value == 'string') {
4292 if (isArray(value)) {
4293 // Recursively convert values (susceptible to call stack limits).
4294 return arrayMap(value, baseToString) + '';
4296 if (isSymbol(value)) {
4297 return symbolToString ? symbolToString.call(value) : '';
4299 var result = (value + '');
4300 return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
4304 * The base implementation of `_.uniqBy` without support for iteratee shorthands.
4307 * @param {Array} array The array to inspect.
4308 * @param {Function} [iteratee] The iteratee invoked per element.
4309 * @param {Function} [comparator] The comparator invoked per element.
4310 * @returns {Array} Returns the new duplicate free array.
4312 function baseUniq(array, iteratee, comparator) {
4314 includes = arrayIncludes,
4315 length = array.length,
4322 includes = arrayIncludesWith;
4324 else if (length >= LARGE_ARRAY_SIZE) {
4325 var set = iteratee ? null : createSet(array);
4327 return setToArray(set);
4330 includes = cacheHas;
4331 seen = new SetCache;
4334 seen = iteratee ? [] : result;
4337 while (++index < length) {
4338 var value = array[index],
4339 computed = iteratee ? iteratee(value) : value;
4341 value = (comparator || value !== 0) ? value : 0;
4342 if (isCommon && computed === computed) {
4343 var seenIndex = seen.length;
4344 while (seenIndex--) {
4345 if (seen[seenIndex] === computed) {
4350 seen.push(computed);
4354 else if (!includes(seen, computed, comparator)) {
4355 if (seen !== result) {
4356 seen.push(computed);
4365 * The base implementation of `_.unset`.
4368 * @param {Object} object The object to modify.
4369 * @param {Array|string} path The property path to unset.
4370 * @returns {boolean} Returns `true` if the property is deleted, else `false`.
4372 function baseUnset(object, path) {
4373 path = castPath(path, object);
4374 object = parent(object, path);
4375 var key = toKey(last(path));
4376 return !(object != null && hasOwnProperty.call(object, key)) || delete object[key];
4380 * The base implementation of `_.update`.
4383 * @param {Object} object The object to modify.
4384 * @param {Array|string} path The path of the property to update.
4385 * @param {Function} updater The function to produce the updated value.
4386 * @param {Function} [customizer] The function to customize path creation.
4387 * @returns {Object} Returns `object`.
4389 function baseUpdate(object, path, updater, customizer) {
4390 return baseSet(object, path, updater(baseGet(object, path)), customizer);
4394 * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
4395 * without support for iteratee shorthands.
4398 * @param {Array} array The array to query.
4399 * @param {Function} predicate The function invoked per iteration.
4400 * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
4401 * @param {boolean} [fromRight] Specify iterating from right to left.
4402 * @returns {Array} Returns the slice of `array`.
4404 function baseWhile(array, predicate, isDrop, fromRight) {
4405 var length = array.length,
4406 index = fromRight ? length : -1;
4408 while ((fromRight ? index-- : ++index < length) &&
4409 predicate(array[index], index, array)) {}
4412 ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
4413 : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
4417 * The base implementation of `wrapperValue` which returns the result of
4418 * performing a sequence of actions on the unwrapped `value`, where each
4419 * successive action is supplied the return value of the previous.
4422 * @param {*} value The unwrapped value.
4423 * @param {Array} actions Actions to perform to resolve the unwrapped value.
4424 * @returns {*} Returns the resolved value.
4426 function baseWrapperValue(value, actions) {
4428 if (result instanceof LazyWrapper) {
4429 result = result.value();
4431 return arrayReduce(actions, function(result, action) {
4432 return action.func.apply(action.thisArg, arrayPush([result], action.args));
4437 * The base implementation of methods like `_.xor`, without support for
4438 * iteratee shorthands, that accepts an array of arrays to inspect.
4441 * @param {Array} arrays The arrays to inspect.
4442 * @param {Function} [iteratee] The iteratee invoked per element.
4443 * @param {Function} [comparator] The comparator invoked per element.
4444 * @returns {Array} Returns the new array of values.
4446 function baseXor(arrays, iteratee, comparator) {
4447 var length = arrays.length;
4449 return length ? baseUniq(arrays[0]) : [];
4452 result = Array(length);
4454 while (++index < length) {
4455 var array = arrays[index],
4458 while (++othIndex < length) {
4459 if (othIndex != index) {
4460 result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
4464 return baseUniq(baseFlatten(result, 1), iteratee, comparator);
4468 * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
4471 * @param {Array} props The property identifiers.
4472 * @param {Array} values The property values.
4473 * @param {Function} assignFunc The function to assign values.
4474 * @returns {Object} Returns the new object.
4476 function baseZipObject(props, values, assignFunc) {
4478 length = props.length,
4479 valsLength = values.length,
4482 while (++index < length) {
4483 var value = index < valsLength ? values[index] : undefined;
4484 assignFunc(result, props[index], value);
4490 * Casts `value` to an empty array if it's not an array like object.
4493 * @param {*} value The value to inspect.
4494 * @returns {Array|Object} Returns the cast array-like object.
4496 function castArrayLikeObject(value) {
4497 return isArrayLikeObject(value) ? value : [];
4501 * Casts `value` to `identity` if it's not a function.
4504 * @param {*} value The value to inspect.
4505 * @returns {Function} Returns cast function.
4507 function castFunction(value) {
4508 return typeof value == 'function' ? value : identity;
4512 * Casts `value` to a path array if it's not one.
4515 * @param {*} value The value to inspect.
4516 * @param {Object} [object] The object to query keys on.
4517 * @returns {Array} Returns the cast property path array.
4519 function castPath(value, object) {
4520 if (isArray(value)) {
4523 return isKey(value, object) ? [value] : stringToPath(toString(value));
4527 * A `baseRest` alias which can be replaced with `identity` by module
4528 * replacement plugins.
4532 * @param {Function} func The function to apply a rest parameter to.
4533 * @returns {Function} Returns the new function.
4535 var castRest = baseRest;
4538 * Casts `array` to a slice if it's needed.
4541 * @param {Array} array The array to inspect.
4542 * @param {number} start The start position.
4543 * @param {number} [end=array.length] The end position.
4544 * @returns {Array} Returns the cast slice.
4546 function castSlice(array, start, end) {
4547 var length = array.length;
4548 end = end === undefined ? length : end;
4549 return (!start && end >= length) ? array : baseSlice(array, start, end);
4553 * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
4556 * @param {number|Object} id The timer id or timeout object of the timer to clear.
4558 var clearTimeout = ctxClearTimeout || function(id) {
4559 return root.clearTimeout(id);
4563 * Creates a clone of `buffer`.
4566 * @param {Buffer} buffer The buffer to clone.
4567 * @param {boolean} [isDeep] Specify a deep clone.
4568 * @returns {Buffer} Returns the cloned buffer.
4570 function cloneBuffer(buffer, isDeep) {
4572 return buffer.slice();
4574 var length = buffer.length,
4575 result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
4577 buffer.copy(result);
4582 * Creates a clone of `arrayBuffer`.
4585 * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
4586 * @returns {ArrayBuffer} Returns the cloned array buffer.
4588 function cloneArrayBuffer(arrayBuffer) {
4589 var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
4590 new Uint8Array(result).set(new Uint8Array(arrayBuffer));
4595 * Creates a clone of `dataView`.
4598 * @param {Object} dataView The data view to clone.
4599 * @param {boolean} [isDeep] Specify a deep clone.
4600 * @returns {Object} Returns the cloned data view.
4602 function cloneDataView(dataView, isDeep) {
4603 var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
4604 return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
4608 * Creates a clone of `map`.
4611 * @param {Object} map The map to clone.
4612 * @param {Function} cloneFunc The function to clone values.
4613 * @param {boolean} [isDeep] Specify a deep clone.
4614 * @returns {Object} Returns the cloned map.
4616 function cloneMap(map, isDeep, cloneFunc) {
4617 var array = isDeep ? cloneFunc(mapToArray(map), CLONE_DEEP_FLAG) : mapToArray(map);
4618 return arrayReduce(array, addMapEntry, new map.constructor);
4622 * Creates a clone of `regexp`.
4625 * @param {Object} regexp The regexp to clone.
4626 * @returns {Object} Returns the cloned regexp.
4628 function cloneRegExp(regexp) {
4629 var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
4630 result.lastIndex = regexp.lastIndex;
4635 * Creates a clone of `set`.
4638 * @param {Object} set The set to clone.
4639 * @param {Function} cloneFunc The function to clone values.
4640 * @param {boolean} [isDeep] Specify a deep clone.
4641 * @returns {Object} Returns the cloned set.
4643 function cloneSet(set, isDeep, cloneFunc) {
4644 var array = isDeep ? cloneFunc(setToArray(set), CLONE_DEEP_FLAG) : setToArray(set);
4645 return arrayReduce(array, addSetEntry, new set.constructor);
4649 * Creates a clone of the `symbol` object.
4652 * @param {Object} symbol The symbol object to clone.
4653 * @returns {Object} Returns the cloned symbol object.
4655 function cloneSymbol(symbol) {
4656 return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
4660 * Creates a clone of `typedArray`.
4663 * @param {Object} typedArray The typed array to clone.
4664 * @param {boolean} [isDeep] Specify a deep clone.
4665 * @returns {Object} Returns the cloned typed array.
4667 function cloneTypedArray(typedArray, isDeep) {
4668 var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
4669 return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
4673 * Compares values to sort them in ascending order.
4676 * @param {*} value The value to compare.
4677 * @param {*} other The other value to compare.
4678 * @returns {number} Returns the sort order indicator for `value`.
4680 function compareAscending(value, other) {
4681 if (value !== other) {
4682 var valIsDefined = value !== undefined,
4683 valIsNull = value === null,
4684 valIsReflexive = value === value,
4685 valIsSymbol = isSymbol(value);
4687 var othIsDefined = other !== undefined,
4688 othIsNull = other === null,
4689 othIsReflexive = other === other,
4690 othIsSymbol = isSymbol(other);
4692 if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
4693 (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
4694 (valIsNull && othIsDefined && othIsReflexive) ||
4695 (!valIsDefined && othIsReflexive) ||
4699 if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
4700 (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
4701 (othIsNull && valIsDefined && valIsReflexive) ||
4702 (!othIsDefined && valIsReflexive) ||
4711 * Used by `_.orderBy` to compare multiple properties of a value to another
4712 * and stable sort them.
4714 * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
4715 * specify an order of "desc" for descending or "asc" for ascending sort order
4716 * of corresponding values.
4719 * @param {Object} object The object to compare.
4720 * @param {Object} other The other object to compare.
4721 * @param {boolean[]|string[]} orders The order to sort by for each property.
4722 * @returns {number} Returns the sort order indicator for `object`.
4724 function compareMultiple(object, other, orders) {
4726 objCriteria = object.criteria,
4727 othCriteria = other.criteria,
4728 length = objCriteria.length,
4729 ordersLength = orders.length;
4731 while (++index < length) {
4732 var result = compareAscending(objCriteria[index], othCriteria[index]);
4734 if (index >= ordersLength) {
4737 var order = orders[index];
4738 return result * (order == 'desc' ? -1 : 1);
4741 // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
4742 // that causes it, under certain circumstances, to provide the same value for
4743 // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
4744 // for more details.
4746 // This also ensures a stable sort in V8 and other engines.
4747 // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
4748 return object.index - other.index;
4752 * Creates an array that is the composition of partially applied arguments,
4753 * placeholders, and provided arguments into a single array of arguments.
4756 * @param {Array} args The provided arguments.
4757 * @param {Array} partials The arguments to prepend to those provided.
4758 * @param {Array} holders The `partials` placeholder indexes.
4759 * @params {boolean} [isCurried] Specify composing for a curried function.
4760 * @returns {Array} Returns the new array of composed arguments.
4762 function composeArgs(args, partials, holders, isCurried) {
4764 argsLength = args.length,
4765 holdersLength = holders.length,
4767 leftLength = partials.length,
4768 rangeLength = nativeMax(argsLength - holdersLength, 0),
4769 result = Array(leftLength + rangeLength),
4770 isUncurried = !isCurried;
4772 while (++leftIndex < leftLength) {
4773 result[leftIndex] = partials[leftIndex];
4775 while (++argsIndex < holdersLength) {
4776 if (isUncurried || argsIndex < argsLength) {
4777 result[holders[argsIndex]] = args[argsIndex];
4780 while (rangeLength--) {
4781 result[leftIndex++] = args[argsIndex++];
4787 * This function is like `composeArgs` except that the arguments composition
4788 * is tailored for `_.partialRight`.
4791 * @param {Array} args The provided arguments.
4792 * @param {Array} partials The arguments to append to those provided.
4793 * @param {Array} holders The `partials` placeholder indexes.
4794 * @params {boolean} [isCurried] Specify composing for a curried function.
4795 * @returns {Array} Returns the new array of composed arguments.
4797 function composeArgsRight(args, partials, holders, isCurried) {
4799 argsLength = args.length,
4801 holdersLength = holders.length,
4803 rightLength = partials.length,
4804 rangeLength = nativeMax(argsLength - holdersLength, 0),
4805 result = Array(rangeLength + rightLength),
4806 isUncurried = !isCurried;
4808 while (++argsIndex < rangeLength) {
4809 result[argsIndex] = args[argsIndex];
4811 var offset = argsIndex;
4812 while (++rightIndex < rightLength) {
4813 result[offset + rightIndex] = partials[rightIndex];
4815 while (++holdersIndex < holdersLength) {
4816 if (isUncurried || argsIndex < argsLength) {
4817 result[offset + holders[holdersIndex]] = args[argsIndex++];
4824 * Copies the values of `source` to `array`.
4827 * @param {Array} source The array to copy values from.
4828 * @param {Array} [array=[]] The array to copy values to.
4829 * @returns {Array} Returns `array`.
4831 function copyArray(source, array) {
4833 length = source.length;
4835 array || (array = Array(length));
4836 while (++index < length) {
4837 array[index] = source[index];
4843 * Copies properties of `source` to `object`.
4846 * @param {Object} source The object to copy properties from.
4847 * @param {Array} props The property identifiers to copy.
4848 * @param {Object} [object={}] The object to copy properties to.
4849 * @param {Function} [customizer] The function to customize copied values.
4850 * @returns {Object} Returns `object`.
4852 function copyObject(source, props, object, customizer) {
4853 var isNew = !object;
4854 object || (object = {});
4857 length = props.length;
4859 while (++index < length) {
4860 var key = props[index];
4862 var newValue = customizer
4863 ? customizer(object[key], source[key], key, object, source)
4866 if (newValue === undefined) {
4867 newValue = source[key];
4870 baseAssignValue(object, key, newValue);
4872 assignValue(object, key, newValue);
4879 * Copies own symbols of `source` to `object`.
4882 * @param {Object} source The object to copy symbols from.
4883 * @param {Object} [object={}] The object to copy symbols to.
4884 * @returns {Object} Returns `object`.
4886 function copySymbols(source, object) {
4887 return copyObject(source, getSymbols(source), object);
4891 * Copies own and inherited symbols of `source` to `object`.
4894 * @param {Object} source The object to copy symbols from.
4895 * @param {Object} [object={}] The object to copy symbols to.
4896 * @returns {Object} Returns `object`.
4898 function copySymbolsIn(source, object) {
4899 return copyObject(source, getSymbolsIn(source), object);
4903 * Creates a function like `_.groupBy`.
4906 * @param {Function} setter The function to set accumulator values.
4907 * @param {Function} [initializer] The accumulator object initializer.
4908 * @returns {Function} Returns the new aggregator function.
4910 function createAggregator(setter, initializer) {
4911 return function(collection, iteratee) {
4912 var func = isArray(collection) ? arrayAggregator : baseAggregator,
4913 accumulator = initializer ? initializer() : {};
4915 return func(collection, setter, getIteratee(iteratee, 2), accumulator);
4920 * Creates a function like `_.assign`.
4923 * @param {Function} assigner The function to assign values.
4924 * @returns {Function} Returns the new assigner function.
4926 function createAssigner(assigner) {
4927 return baseRest(function(object, sources) {
4929 length = sources.length,
4930 customizer = length > 1 ? sources[length - 1] : undefined,
4931 guard = length > 2 ? sources[2] : undefined;
4933 customizer = (assigner.length > 3 && typeof customizer == 'function')
4934 ? (length--, customizer)
4937 if (guard && isIterateeCall(sources[0], sources[1], guard)) {
4938 customizer = length < 3 ? undefined : customizer;
4941 object = Object(object);
4942 while (++index < length) {
4943 var source = sources[index];
4945 assigner(object, source, index, customizer);
4953 * Creates a `baseEach` or `baseEachRight` function.
4956 * @param {Function} eachFunc The function to iterate over a collection.
4957 * @param {boolean} [fromRight] Specify iterating from right to left.
4958 * @returns {Function} Returns the new base function.
4960 function createBaseEach(eachFunc, fromRight) {
4961 return function(collection, iteratee) {
4962 if (collection == null) {
4965 if (!isArrayLike(collection)) {
4966 return eachFunc(collection, iteratee);
4968 var length = collection.length,
4969 index = fromRight ? length : -1,
4970 iterable = Object(collection);
4972 while ((fromRight ? index-- : ++index < length)) {
4973 if (iteratee(iterable[index], index, iterable) === false) {
4982 * Creates a base function for methods like `_.forIn` and `_.forOwn`.
4985 * @param {boolean} [fromRight] Specify iterating from right to left.
4986 * @returns {Function} Returns the new base function.
4988 function createBaseFor(fromRight) {
4989 return function(object, iteratee, keysFunc) {
4991 iterable = Object(object),
4992 props = keysFunc(object),
4993 length = props.length;
4996 var key = props[fromRight ? length : ++index];
4997 if (iteratee(iterable[key], key, iterable) === false) {
5006 * Creates a function that wraps `func` to invoke it with the optional `this`
5007 * binding of `thisArg`.
5010 * @param {Function} func The function to wrap.
5011 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5012 * @param {*} [thisArg] The `this` binding of `func`.
5013 * @returns {Function} Returns the new wrapped function.
5015 function createBind(func, bitmask, thisArg) {
5016 var isBind = bitmask & WRAP_BIND_FLAG,
5017 Ctor = createCtor(func);
5019 function wrapper() {
5020 var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
5021 return fn.apply(isBind ? thisArg : this, arguments);
5027 * Creates a function like `_.lowerFirst`.
5030 * @param {string} methodName The name of the `String` case method to use.
5031 * @returns {Function} Returns the new case function.
5033 function createCaseFirst(methodName) {
5034 return function(string) {
5035 string = toString(string);
5037 var strSymbols = hasUnicode(string)
5038 ? stringToArray(string)
5041 var chr = strSymbols
5045 var trailing = strSymbols
5046 ? castSlice(strSymbols, 1).join('')
5049 return chr[methodName]() + trailing;
5054 * Creates a function like `_.camelCase`.
5057 * @param {Function} callback The function to combine each word.
5058 * @returns {Function} Returns the new compounder function.
5060 function createCompounder(callback) {
5061 return function(string) {
5062 return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
5067 * Creates a function that produces an instance of `Ctor` regardless of
5068 * whether it was invoked as part of a `new` expression or by `call` or `apply`.
5071 * @param {Function} Ctor The constructor to wrap.
5072 * @returns {Function} Returns the new wrapped function.
5074 function createCtor(Ctor) {
5076 // Use a `switch` statement to work with class constructors. See
5077 // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
5078 // for more details.
5079 var args = arguments;
5080 switch (args.length) {
5081 case 0: return new Ctor;
5082 case 1: return new Ctor(args[0]);
5083 case 2: return new Ctor(args[0], args[1]);
5084 case 3: return new Ctor(args[0], args[1], args[2]);
5085 case 4: return new Ctor(args[0], args[1], args[2], args[3]);
5086 case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
5087 case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
5088 case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
5090 var thisBinding = baseCreate(Ctor.prototype),
5091 result = Ctor.apply(thisBinding, args);
5093 // Mimic the constructor's `return` behavior.
5094 // See https://es5.github.io/#x13.2.2 for more details.
5095 return isObject(result) ? result : thisBinding;
5100 * Creates a function that wraps `func` to enable currying.
5103 * @param {Function} func The function to wrap.
5104 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5105 * @param {number} arity The arity of `func`.
5106 * @returns {Function} Returns the new wrapped function.
5108 function createCurry(func, bitmask, arity) {
5109 var Ctor = createCtor(func);
5111 function wrapper() {
5112 var length = arguments.length,
5113 args = Array(length),
5115 placeholder = getHolder(wrapper);
5118 args[index] = arguments[index];
5120 var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
5122 : replaceHolders(args, placeholder);
5124 length -= holders.length;
5125 if (length < arity) {
5126 return createRecurry(
5127 func, bitmask, createHybrid, wrapper.placeholder, undefined,
5128 args, holders, undefined, undefined, arity - length);
5130 var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
5131 return apply(fn, this, args);
5137 * Creates a `_.find` or `_.findLast` function.
5140 * @param {Function} findIndexFunc The function to find the collection index.
5141 * @returns {Function} Returns the new find function.
5143 function createFind(findIndexFunc) {
5144 return function(collection, predicate, fromIndex) {
5145 var iterable = Object(collection);
5146 if (!isArrayLike(collection)) {
5147 var iteratee = getIteratee(predicate, 3);
5148 collection = keys(collection);
5149 predicate = function(key) { return iteratee(iterable[key], key, iterable); };
5151 var index = findIndexFunc(collection, predicate, fromIndex);
5152 return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
5157 * Creates a `_.flow` or `_.flowRight` function.
5160 * @param {boolean} [fromRight] Specify iterating from right to left.
5161 * @returns {Function} Returns the new flow function.
5163 function createFlow(fromRight) {
5164 return flatRest(function(funcs) {
5165 var length = funcs.length,
5167 prereq = LodashWrapper.prototype.thru;
5173 var func = funcs[index];
5174 if (typeof func != 'function') {
5175 throw new TypeError(FUNC_ERROR_TEXT);
5177 if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
5178 var wrapper = new LodashWrapper([], true);
5181 index = wrapper ? index : length;
5182 while (++index < length) {
5183 func = funcs[index];
5185 var funcName = getFuncName(func),
5186 data = funcName == 'wrapper' ? getData(func) : undefined;
5188 if (data && isLaziable(data[0]) &&
5189 data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
5190 !data[4].length && data[9] == 1
5192 wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
5194 wrapper = (func.length == 1 && isLaziable(func))
5195 ? wrapper[funcName]()
5196 : wrapper.thru(func);
5200 var args = arguments,
5203 if (wrapper && args.length == 1 &&
5204 isArray(value) && value.length >= LARGE_ARRAY_SIZE) {
5205 return wrapper.plant(value).value();
5208 result = length ? funcs[index].apply(this, args) : value;
5210 while (++index < length) {
5211 result = funcs[index].call(this, result);
5219 * Creates a function that wraps `func` to invoke it with optional `this`
5220 * binding of `thisArg`, partial application, and currying.
5223 * @param {Function|string} func The function or method name to wrap.
5224 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5225 * @param {*} [thisArg] The `this` binding of `func`.
5226 * @param {Array} [partials] The arguments to prepend to those provided to
5228 * @param {Array} [holders] The `partials` placeholder indexes.
5229 * @param {Array} [partialsRight] The arguments to append to those provided
5230 * to the new function.
5231 * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
5232 * @param {Array} [argPos] The argument positions of the new function.
5233 * @param {number} [ary] The arity cap of `func`.
5234 * @param {number} [arity] The arity of `func`.
5235 * @returns {Function} Returns the new wrapped function.
5237 function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
5238 var isAry = bitmask & WRAP_ARY_FLAG,
5239 isBind = bitmask & WRAP_BIND_FLAG,
5240 isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
5241 isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
5242 isFlip = bitmask & WRAP_FLIP_FLAG,
5243 Ctor = isBindKey ? undefined : createCtor(func);
5245 function wrapper() {
5246 var length = arguments.length,
5247 args = Array(length),
5251 args[index] = arguments[index];
5254 var placeholder = getHolder(wrapper),
5255 holdersCount = countHolders(args, placeholder);
5258 args = composeArgs(args, partials, holders, isCurried);
5260 if (partialsRight) {
5261 args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
5263 length -= holdersCount;
5264 if (isCurried && length < arity) {
5265 var newHolders = replaceHolders(args, placeholder);
5266 return createRecurry(
5267 func, bitmask, createHybrid, wrapper.placeholder, thisArg,
5268 args, newHolders, argPos, ary, arity - length
5271 var thisBinding = isBind ? thisArg : this,
5272 fn = isBindKey ? thisBinding[func] : func;
5274 length = args.length;
5276 args = reorder(args, argPos);
5277 } else if (isFlip && length > 1) {
5280 if (isAry && ary < length) {
5283 if (this && this !== root && this instanceof wrapper) {
5284 fn = Ctor || createCtor(fn);
5286 return fn.apply(thisBinding, args);
5292 * Creates a function like `_.invertBy`.
5295 * @param {Function} setter The function to set accumulator values.
5296 * @param {Function} toIteratee The function to resolve iteratees.
5297 * @returns {Function} Returns the new inverter function.
5299 function createInverter(setter, toIteratee) {
5300 return function(object, iteratee) {
5301 return baseInverter(object, setter, toIteratee(iteratee), {});
5306 * Creates a function that performs a mathematical operation on two values.
5309 * @param {Function} operator The function to perform the operation.
5310 * @param {number} [defaultValue] The value used for `undefined` arguments.
5311 * @returns {Function} Returns the new mathematical operation function.
5313 function createMathOperation(operator, defaultValue) {
5314 return function(value, other) {
5316 if (value === undefined && other === undefined) {
5317 return defaultValue;
5319 if (value !== undefined) {
5322 if (other !== undefined) {
5323 if (result === undefined) {
5326 if (typeof value == 'string' || typeof other == 'string') {
5327 value = baseToString(value);
5328 other = baseToString(other);
5330 value = baseToNumber(value);
5331 other = baseToNumber(other);
5333 result = operator(value, other);
5340 * Creates a function like `_.over`.
5343 * @param {Function} arrayFunc The function to iterate over iteratees.
5344 * @returns {Function} Returns the new over function.
5346 function createOver(arrayFunc) {
5347 return flatRest(function(iteratees) {
5348 iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
5349 return baseRest(function(args) {
5351 return arrayFunc(iteratees, function(iteratee) {
5352 return apply(iteratee, thisArg, args);
5359 * Creates the padding for `string` based on `length`. The `chars` string
5360 * is truncated if the number of characters exceeds `length`.
5363 * @param {number} length The padding length.
5364 * @param {string} [chars=' '] The string used as padding.
5365 * @returns {string} Returns the padding for `string`.
5367 function createPadding(length, chars) {
5368 chars = chars === undefined ? ' ' : baseToString(chars);
5370 var charsLength = chars.length;
5371 if (charsLength < 2) {
5372 return charsLength ? baseRepeat(chars, length) : chars;
5374 var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
5375 return hasUnicode(chars)
5376 ? castSlice(stringToArray(result), 0, length).join('')
5377 : result.slice(0, length);
5381 * Creates a function that wraps `func` to invoke it with the `this` binding
5382 * of `thisArg` and `partials` prepended to the arguments it receives.
5385 * @param {Function} func The function to wrap.
5386 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5387 * @param {*} thisArg The `this` binding of `func`.
5388 * @param {Array} partials The arguments to prepend to those provided to
5390 * @returns {Function} Returns the new wrapped function.
5392 function createPartial(func, bitmask, thisArg, partials) {
5393 var isBind = bitmask & WRAP_BIND_FLAG,
5394 Ctor = createCtor(func);
5396 function wrapper() {
5398 argsLength = arguments.length,
5400 leftLength = partials.length,
5401 args = Array(leftLength + argsLength),
5402 fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
5404 while (++leftIndex < leftLength) {
5405 args[leftIndex] = partials[leftIndex];
5407 while (argsLength--) {
5408 args[leftIndex++] = arguments[++argsIndex];
5410 return apply(fn, isBind ? thisArg : this, args);
5416 * Creates a `_.range` or `_.rangeRight` function.
5419 * @param {boolean} [fromRight] Specify iterating from right to left.
5420 * @returns {Function} Returns the new range function.
5422 function createRange(fromRight) {
5423 return function(start, end, step) {
5424 if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
5425 end = step = undefined;
5427 // Ensure the sign of `-0` is preserved.
5428 start = toFinite(start);
5429 if (end === undefined) {
5433 end = toFinite(end);
5435 step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);
5436 return baseRange(start, end, step, fromRight);
5441 * Creates a function that performs a relational operation on two values.
5444 * @param {Function} operator The function to perform the operation.
5445 * @returns {Function} Returns the new relational operation function.
5447 function createRelationalOperation(operator) {
5448 return function(value, other) {
5449 if (!(typeof value == 'string' && typeof other == 'string')) {
5450 value = toNumber(value);
5451 other = toNumber(other);
5453 return operator(value, other);
5458 * Creates a function that wraps `func` to continue currying.
5461 * @param {Function} func The function to wrap.
5462 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5463 * @param {Function} wrapFunc The function to create the `func` wrapper.
5464 * @param {*} placeholder The placeholder value.
5465 * @param {*} [thisArg] The `this` binding of `func`.
5466 * @param {Array} [partials] The arguments to prepend to those provided to
5468 * @param {Array} [holders] The `partials` placeholder indexes.
5469 * @param {Array} [argPos] The argument positions of the new function.
5470 * @param {number} [ary] The arity cap of `func`.
5471 * @param {number} [arity] The arity of `func`.
5472 * @returns {Function} Returns the new wrapped function.
5474 function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
5475 var isCurry = bitmask & WRAP_CURRY_FLAG,
5476 newHolders = isCurry ? holders : undefined,
5477 newHoldersRight = isCurry ? undefined : holders,
5478 newPartials = isCurry ? partials : undefined,
5479 newPartialsRight = isCurry ? undefined : partials;
5481 bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
5482 bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
5484 if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
5485 bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
5488 func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
5489 newHoldersRight, argPos, ary, arity
5492 var result = wrapFunc.apply(undefined, newData);
5493 if (isLaziable(func)) {
5494 setData(result, newData);
5496 result.placeholder = placeholder;
5497 return setWrapToString(result, func, bitmask);
5501 * Creates a function like `_.round`.
5504 * @param {string} methodName The name of the `Math` method to use when rounding.
5505 * @returns {Function} Returns the new round function.
5507 function createRound(methodName) {
5508 var func = Math[methodName];
5509 return function(number, precision) {
5510 number = toNumber(number);
5511 precision = nativeMin(toInteger(precision), 292);
5513 // Shift with exponential notation to avoid floating-point issues.
5514 // See [MDN](https://mdn.io/round#Examples) for more details.
5515 var pair = (toString(number) + 'e').split('e'),
5516 value = func(pair[0] + 'e' + (+pair[1] + precision));
5518 pair = (toString(value) + 'e').split('e');
5519 return +(pair[0] + 'e' + (+pair[1] - precision));
5521 return func(number);
5526 * Creates a set object of `values`.
5529 * @param {Array} values The values to add to the set.
5530 * @returns {Object} Returns the new set.
5532 var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
5533 return new Set(values);
5537 * Creates a `_.toPairs` or `_.toPairsIn` function.
5540 * @param {Function} keysFunc The function to get the keys of a given object.
5541 * @returns {Function} Returns the new pairs function.
5543 function createToPairs(keysFunc) {
5544 return function(object) {
5545 var tag = getTag(object);
5546 if (tag == mapTag) {
5547 return mapToArray(object);
5549 if (tag == setTag) {
5550 return setToPairs(object);
5552 return baseToPairs(object, keysFunc(object));
5557 * Creates a function that either curries or invokes `func` with optional
5558 * `this` binding and partially applied arguments.
5561 * @param {Function|string} func The function or method name to wrap.
5562 * @param {number} bitmask The bitmask flags.
5565 * 4 - `_.curry` or `_.curryRight` of a bound function
5567 * 16 - `_.curryRight`
5569 * 64 - `_.partialRight`
5573 * @param {*} [thisArg] The `this` binding of `func`.
5574 * @param {Array} [partials] The arguments to be partially applied.
5575 * @param {Array} [holders] The `partials` placeholder indexes.
5576 * @param {Array} [argPos] The argument positions of the new function.
5577 * @param {number} [ary] The arity cap of `func`.
5578 * @param {number} [arity] The arity of `func`.
5579 * @returns {Function} Returns the new wrapped function.
5581 function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
5582 var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
5583 if (!isBindKey && typeof func != 'function') {
5584 throw new TypeError(FUNC_ERROR_TEXT);
5586 var length = partials ? partials.length : 0;
5588 bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
5589 partials = holders = undefined;
5591 ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
5592 arity = arity === undefined ? arity : toInteger(arity);
5593 length -= holders ? holders.length : 0;
5595 if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
5596 var partialsRight = partials,
5597 holdersRight = holders;
5599 partials = holders = undefined;
5601 var data = isBindKey ? undefined : getData(func);
5604 func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
5609 mergeData(newData, data);
5612 bitmask = newData[1];
5613 thisArg = newData[2];
5614 partials = newData[3];
5615 holders = newData[4];
5616 arity = newData[9] = newData[9] == null
5617 ? (isBindKey ? 0 : func.length)
5618 : nativeMax(newData[9] - length, 0);
5620 if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
5621 bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
5623 if (!bitmask || bitmask == WRAP_BIND_FLAG) {
5624 var result = createBind(func, bitmask, thisArg);
5625 } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
5626 result = createCurry(func, bitmask, arity);
5627 } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
5628 result = createPartial(func, bitmask, thisArg, partials);
5630 result = createHybrid.apply(undefined, newData);
5632 var setter = data ? baseSetData : setData;
5633 return setWrapToString(setter(result, newData), func, bitmask);
5637 * A specialized version of `baseIsEqualDeep` for arrays with support for
5638 * partial deep comparisons.
5641 * @param {Array} array The array to compare.
5642 * @param {Array} other The other array to compare.
5643 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
5644 * @param {Function} customizer The function to customize comparisons.
5645 * @param {Function} equalFunc The function to determine equivalents of values.
5646 * @param {Object} stack Tracks traversed `array` and `other` objects.
5647 * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
5649 function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
5650 var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
5651 arrLength = array.length,
5652 othLength = other.length;
5654 if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
5657 // Assume cyclic values are equal.
5658 var stacked = stack.get(array);
5659 if (stacked && stack.get(other)) {
5660 return stacked == other;
5664 seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
5666 stack.set(array, other);
5667 stack.set(other, array);
5669 // Ignore non-index properties.
5670 while (++index < arrLength) {
5671 var arrValue = array[index],
5672 othValue = other[index];
5675 var compared = isPartial
5676 ? customizer(othValue, arrValue, index, other, array, stack)
5677 : customizer(arrValue, othValue, index, array, other, stack);
5679 if (compared !== undefined) {
5686 // Recursively compare arrays (susceptible to call stack limits).
5688 if (!arraySome(other, function(othValue, othIndex) {
5689 if (!cacheHas(seen, othIndex) &&
5690 (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
5691 return seen.push(othIndex);
5698 arrValue === othValue ||
5699 equalFunc(arrValue, othValue, bitmask, customizer, stack)
5705 stack['delete'](array);
5706 stack['delete'](other);
5711 * A specialized version of `baseIsEqualDeep` for comparing objects of
5712 * the same `toStringTag`.
5714 * **Note:** This function only supports comparing values with tags of
5715 * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
5718 * @param {Object} object The object to compare.
5719 * @param {Object} other The other object to compare.
5720 * @param {string} tag The `toStringTag` of the objects to compare.
5721 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
5722 * @param {Function} customizer The function to customize comparisons.
5723 * @param {Function} equalFunc The function to determine equivalents of values.
5724 * @param {Object} stack Tracks traversed `object` and `other` objects.
5725 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
5727 function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
5730 if ((object.byteLength != other.byteLength) ||
5731 (object.byteOffset != other.byteOffset)) {
5734 object = object.buffer;
5735 other = other.buffer;
5737 case arrayBufferTag:
5738 if ((object.byteLength != other.byteLength) ||
5739 !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
5747 // Coerce booleans to `1` or `0` and dates to milliseconds.
5748 // Invalid dates are coerced to `NaN`.
5749 return eq(+object, +other);
5752 return object.name == other.name && object.message == other.message;
5756 // Coerce regexes to strings and treat strings, primitives and objects,
5757 // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
5758 // for more details.
5759 return object == (other + '');
5762 var convert = mapToArray;
5765 var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
5766 convert || (convert = setToArray);
5768 if (object.size != other.size && !isPartial) {
5771 // Assume cyclic values are equal.
5772 var stacked = stack.get(object);
5774 return stacked == other;
5776 bitmask |= COMPARE_UNORDERED_FLAG;
5778 // Recursively compare objects (susceptible to call stack limits).
5779 stack.set(object, other);
5780 var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
5781 stack['delete'](object);
5785 if (symbolValueOf) {
5786 return symbolValueOf.call(object) == symbolValueOf.call(other);
5793 * A specialized version of `baseIsEqualDeep` for objects with support for
5794 * partial deep comparisons.
5797 * @param {Object} object The object to compare.
5798 * @param {Object} other The other object to compare.
5799 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
5800 * @param {Function} customizer The function to customize comparisons.
5801 * @param {Function} equalFunc The function to determine equivalents of values.
5802 * @param {Object} stack Tracks traversed `object` and `other` objects.
5803 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
5805 function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
5806 var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
5807 objProps = keys(object),
5808 objLength = objProps.length,
5809 othProps = keys(other),
5810 othLength = othProps.length;
5812 if (objLength != othLength && !isPartial) {
5815 var index = objLength;
5817 var key = objProps[index];
5818 if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
5822 // Assume cyclic values are equal.
5823 var stacked = stack.get(object);
5824 if (stacked && stack.get(other)) {
5825 return stacked == other;
5828 stack.set(object, other);
5829 stack.set(other, object);
5831 var skipCtor = isPartial;
5832 while (++index < objLength) {
5833 key = objProps[index];
5834 var objValue = object[key],
5835 othValue = other[key];
5838 var compared = isPartial
5839 ? customizer(othValue, objValue, key, other, object, stack)
5840 : customizer(objValue, othValue, key, object, other, stack);
5842 // Recursively compare objects (susceptible to call stack limits).
5843 if (!(compared === undefined
5844 ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
5850 skipCtor || (skipCtor = key == 'constructor');
5852 if (result && !skipCtor) {
5853 var objCtor = object.constructor,
5854 othCtor = other.constructor;
5856 // Non `Object` object instances with different constructors are not equal.
5857 if (objCtor != othCtor &&
5858 ('constructor' in object && 'constructor' in other) &&
5859 !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
5860 typeof othCtor == 'function' && othCtor instanceof othCtor)) {
5864 stack['delete'](object);
5865 stack['delete'](other);
5870 * A specialized version of `baseRest` which flattens the rest array.
5873 * @param {Function} func The function to apply a rest parameter to.
5874 * @returns {Function} Returns the new function.
5876 function flatRest(func) {
5877 return setToString(overRest(func, undefined, flatten), func + '');
5881 * Creates an array of own enumerable property names and symbols of `object`.
5884 * @param {Object} object The object to query.
5885 * @returns {Array} Returns the array of property names and symbols.
5887 function getAllKeys(object) {
5888 return baseGetAllKeys(object, keys, getSymbols);
5892 * Creates an array of own and inherited enumerable property names and
5893 * symbols of `object`.
5896 * @param {Object} object The object to query.
5897 * @returns {Array} Returns the array of property names and symbols.
5899 function getAllKeysIn(object) {
5900 return baseGetAllKeys(object, keysIn, getSymbolsIn);
5904 * Gets metadata for `func`.
5907 * @param {Function} func The function to query.
5908 * @returns {*} Returns the metadata for `func`.
5910 var getData = !metaMap ? noop : function(func) {
5911 return metaMap.get(func);
5915 * Gets the name of `func`.
5918 * @param {Function} func The function to query.
5919 * @returns {string} Returns the function name.
5921 function getFuncName(func) {
5922 var result = (func.name + ''),
5923 array = realNames[result],
5924 length = hasOwnProperty.call(realNames, result) ? array.length : 0;
5927 var data = array[length],
5928 otherFunc = data.func;
5929 if (otherFunc == null || otherFunc == func) {
5937 * Gets the argument placeholder value for `func`.
5940 * @param {Function} func The function to inspect.
5941 * @returns {*} Returns the placeholder value.
5943 function getHolder(func) {
5944 var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
5945 return object.placeholder;
5949 * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
5950 * this function returns the custom method, otherwise it returns `baseIteratee`.
5951 * If arguments are provided, the chosen function is invoked with them and
5952 * its result is returned.
5955 * @param {*} [value] The value to convert to an iteratee.
5956 * @param {number} [arity] The arity of the created iteratee.
5957 * @returns {Function} Returns the chosen function or its result.
5959 function getIteratee() {
5960 var result = lodash.iteratee || iteratee;
5961 result = result === iteratee ? baseIteratee : result;
5962 return arguments.length ? result(arguments[0], arguments[1]) : result;
5966 * Gets the data for `map`.
5969 * @param {Object} map The map to query.
5970 * @param {string} key The reference key.
5971 * @returns {*} Returns the map data.
5973 function getMapData(map, key) {
5974 var data = map.__data__;
5975 return isKeyable(key)
5976 ? data[typeof key == 'string' ? 'string' : 'hash']
5981 * Gets the property names, values, and compare flags of `object`.
5984 * @param {Object} object The object to query.
5985 * @returns {Array} Returns the match data of `object`.
5987 function getMatchData(object) {
5988 var result = keys(object),
5989 length = result.length;
5992 var key = result[length],
5993 value = object[key];
5995 result[length] = [key, value, isStrictComparable(value)];
6001 * Gets the native function at `key` of `object`.
6004 * @param {Object} object The object to query.
6005 * @param {string} key The key of the method to get.
6006 * @returns {*} Returns the function if it's native, else `undefined`.
6008 function getNative(object, key) {
6009 var value = getValue(object, key);
6010 return baseIsNative(value) ? value : undefined;
6014 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
6017 * @param {*} value The value to query.
6018 * @returns {string} Returns the raw `toStringTag`.
6020 function getRawTag(value) {
6021 var isOwn = hasOwnProperty.call(value, symToStringTag),
6022 tag = value[symToStringTag];
6025 value[symToStringTag] = undefined;
6026 var unmasked = true;
6029 var result = nativeObjectToString.call(value);
6032 value[symToStringTag] = tag;
6034 delete value[symToStringTag];
6041 * Creates an array of the own enumerable symbols of `object`.
6044 * @param {Object} object The object to query.
6045 * @returns {Array} Returns the array of symbols.
6047 var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray;
6050 * Creates an array of the own and inherited enumerable symbols of `object`.
6053 * @param {Object} object The object to query.
6054 * @returns {Array} Returns the array of symbols.
6056 var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
6059 arrayPush(result, getSymbols(object));
6060 object = getPrototype(object);
6066 * Gets the `toStringTag` of `value`.
6069 * @param {*} value The value to query.
6070 * @returns {string} Returns the `toStringTag`.
6072 var getTag = baseGetTag;
6074 // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
6075 if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
6076 (Map && getTag(new Map) != mapTag) ||
6077 (Promise && getTag(Promise.resolve()) != promiseTag) ||
6078 (Set && getTag(new Set) != setTag) ||
6079 (WeakMap && getTag(new WeakMap) != weakMapTag)) {
6080 getTag = function(value) {
6081 var result = baseGetTag(value),
6082 Ctor = result == objectTag ? value.constructor : undefined,
6083 ctorString = Ctor ? toSource(Ctor) : '';
6086 switch (ctorString) {
6087 case dataViewCtorString: return dataViewTag;
6088 case mapCtorString: return mapTag;
6089 case promiseCtorString: return promiseTag;
6090 case setCtorString: return setTag;
6091 case weakMapCtorString: return weakMapTag;
6099 * Gets the view, applying any `transforms` to the `start` and `end` positions.
6102 * @param {number} start The start of the view.
6103 * @param {number} end The end of the view.
6104 * @param {Array} transforms The transformations to apply to the view.
6105 * @returns {Object} Returns an object containing the `start` and `end`
6106 * positions of the view.
6108 function getView(start, end, transforms) {
6110 length = transforms.length;
6112 while (++index < length) {
6113 var data = transforms[index],
6116 switch (data.type) {
6117 case 'drop': start += size; break;
6118 case 'dropRight': end -= size; break;
6119 case 'take': end = nativeMin(end, start + size); break;
6120 case 'takeRight': start = nativeMax(start, end - size); break;
6123 return { 'start': start, 'end': end };
6127 * Extracts wrapper details from the `source` body comment.
6130 * @param {string} source The source to inspect.
6131 * @returns {Array} Returns the wrapper details.
6133 function getWrapDetails(source) {
6134 var match = source.match(reWrapDetails);
6135 return match ? match[1].split(reSplitDetails) : [];
6139 * Checks if `path` exists on `object`.
6142 * @param {Object} object The object to query.
6143 * @param {Array|string} path The path to check.
6144 * @param {Function} hasFunc The function to check properties.
6145 * @returns {boolean} Returns `true` if `path` exists, else `false`.
6147 function hasPath(object, path, hasFunc) {
6148 path = castPath(path, object);
6151 length = path.length,
6154 while (++index < length) {
6155 var key = toKey(path[index]);
6156 if (!(result = object != null && hasFunc(object, key))) {
6159 object = object[key];
6161 if (result || ++index != length) {
6164 length = object == null ? 0 : object.length;
6165 return !!length && isLength(length) && isIndex(key, length) &&
6166 (isArray(object) || isArguments(object));
6170 * Initializes an array clone.
6173 * @param {Array} array The array to clone.
6174 * @returns {Array} Returns the initialized clone.
6176 function initCloneArray(array) {
6177 var length = array.length,
6178 result = array.constructor(length);
6180 // Add properties assigned by `RegExp#exec`.
6181 if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
6182 result.index = array.index;
6183 result.input = array.input;
6189 * Initializes an object clone.
6192 * @param {Object} object The object to clone.
6193 * @returns {Object} Returns the initialized clone.
6195 function initCloneObject(object) {
6196 return (typeof object.constructor == 'function' && !isPrototype(object))
6197 ? baseCreate(getPrototype(object))
6202 * Initializes an object clone based on its `toStringTag`.
6204 * **Note:** This function only supports cloning values with tags of
6205 * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
6208 * @param {Object} object The object to clone.
6209 * @param {string} tag The `toStringTag` of the object to clone.
6210 * @param {Function} cloneFunc The function to clone values.
6211 * @param {boolean} [isDeep] Specify a deep clone.
6212 * @returns {Object} Returns the initialized clone.
6214 function initCloneByTag(object, tag, cloneFunc, isDeep) {
6215 var Ctor = object.constructor;
6217 case arrayBufferTag:
6218 return cloneArrayBuffer(object);
6222 return new Ctor(+object);
6225 return cloneDataView(object, isDeep);
6227 case float32Tag: case float64Tag:
6228 case int8Tag: case int16Tag: case int32Tag:
6229 case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
6230 return cloneTypedArray(object, isDeep);
6233 return cloneMap(object, isDeep, cloneFunc);
6237 return new Ctor(object);
6240 return cloneRegExp(object);
6243 return cloneSet(object, isDeep, cloneFunc);
6246 return cloneSymbol(object);
6251 * Inserts wrapper `details` in a comment at the top of the `source` body.
6254 * @param {string} source The source to modify.
6255 * @returns {Array} details The details to insert.
6256 * @returns {string} Returns the modified source.
6258 function insertWrapDetails(source, details) {
6259 var length = details.length;
6263 var lastIndex = length - 1;
6264 details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
6265 details = details.join(length > 2 ? ', ' : ' ');
6266 return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
6270 * Checks if `value` is a flattenable `arguments` object or array.
6273 * @param {*} value The value to check.
6274 * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
6276 function isFlattenable(value) {
6277 return isArray(value) || isArguments(value) ||
6278 !!(spreadableSymbol && value && value[spreadableSymbol]);
6282 * Checks if `value` is a valid array-like index.
6285 * @param {*} value The value to check.
6286 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
6287 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
6289 function isIndex(value, length) {
6290 length = length == null ? MAX_SAFE_INTEGER : length;
6292 (typeof value == 'number' || reIsUint.test(value)) &&
6293 (value > -1 && value % 1 == 0 && value < length);
6297 * Checks if the given arguments are from an iteratee call.
6300 * @param {*} value The potential iteratee value argument.
6301 * @param {*} index The potential iteratee index or key argument.
6302 * @param {*} object The potential iteratee object argument.
6303 * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
6306 function isIterateeCall(value, index, object) {
6307 if (!isObject(object)) {
6310 var type = typeof index;
6311 if (type == 'number'
6312 ? (isArrayLike(object) && isIndex(index, object.length))
6313 : (type == 'string' && index in object)
6315 return eq(object[index], value);
6321 * Checks if `value` is a property name and not a property path.
6324 * @param {*} value The value to check.
6325 * @param {Object} [object] The object to query keys on.
6326 * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
6328 function isKey(value, object) {
6329 if (isArray(value)) {
6332 var type = typeof value;
6333 if (type == 'number' || type == 'symbol' || type == 'boolean' ||
6334 value == null || isSymbol(value)) {
6337 return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
6338 (object != null && value in Object(object));
6342 * Checks if `value` is suitable for use as unique object key.
6345 * @param {*} value The value to check.
6346 * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
6348 function isKeyable(value) {
6349 var type = typeof value;
6350 return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
6351 ? (value !== '__proto__')
6356 * Checks if `func` has a lazy counterpart.
6359 * @param {Function} func The function to check.
6360 * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
6363 function isLaziable(func) {
6364 var funcName = getFuncName(func),
6365 other = lodash[funcName];
6367 if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
6370 if (func === other) {
6373 var data = getData(other);
6374 return !!data && func === data[0];
6378 * Checks if `func` has its source masked.
6381 * @param {Function} func The function to check.
6382 * @returns {boolean} Returns `true` if `func` is masked, else `false`.
6384 function isMasked(func) {
6385 return !!maskSrcKey && (maskSrcKey in func);
6389 * Checks if `func` is capable of being masked.
6392 * @param {*} value The value to check.
6393 * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
6395 var isMaskable = coreJsData ? isFunction : stubFalse;
6398 * Checks if `value` is likely a prototype object.
6401 * @param {*} value The value to check.
6402 * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
6404 function isPrototype(value) {
6405 var Ctor = value && value.constructor,
6406 proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
6408 return value === proto;
6412 * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
6415 * @param {*} value The value to check.
6416 * @returns {boolean} Returns `true` if `value` if suitable for strict
6417 * equality comparisons, else `false`.
6419 function isStrictComparable(value) {
6420 return value === value && !isObject(value);
6424 * A specialized version of `matchesProperty` for source values suitable
6425 * for strict equality comparisons, i.e. `===`.
6428 * @param {string} key The key of the property to get.
6429 * @param {*} srcValue The value to match.
6430 * @returns {Function} Returns the new spec function.
6432 function matchesStrictComparable(key, srcValue) {
6433 return function(object) {
6434 if (object == null) {
6437 return object[key] === srcValue &&
6438 (srcValue !== undefined || (key in Object(object)));
6443 * A specialized version of `_.memoize` which clears the memoized function's
6444 * cache when it exceeds `MAX_MEMOIZE_SIZE`.
6447 * @param {Function} func The function to have its output memoized.
6448 * @returns {Function} Returns the new memoized function.
6450 function memoizeCapped(func) {
6451 var result = memoize(func, function(key) {
6452 if (cache.size === MAX_MEMOIZE_SIZE) {
6458 var cache = result.cache;
6463 * Merges the function metadata of `source` into `data`.
6465 * Merging metadata reduces the number of wrappers used to invoke a function.
6466 * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
6467 * may be applied regardless of execution order. Methods like `_.ary` and
6468 * `_.rearg` modify function arguments, making the order in which they are
6469 * executed important, preventing the merging of metadata. However, we make
6470 * an exception for a safe combined case where curried functions have `_.ary`
6471 * and or `_.rearg` applied.
6474 * @param {Array} data The destination metadata.
6475 * @param {Array} source The source metadata.
6476 * @returns {Array} Returns `data`.
6478 function mergeData(data, source) {
6479 var bitmask = data[1],
6480 srcBitmask = source[1],
6481 newBitmask = bitmask | srcBitmask,
6482 isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
6485 ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
6486 ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
6487 ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));
6489 // Exit early if metadata can't be merged.
6490 if (!(isCommon || isCombo)) {
6493 // Use source `thisArg` if available.
6494 if (srcBitmask & WRAP_BIND_FLAG) {
6495 data[2] = source[2];
6496 // Set when currying a bound function.
6497 newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
6499 // Compose partial arguments.
6500 var value = source[3];
6502 var partials = data[3];
6503 data[3] = partials ? composeArgs(partials, value, source[4]) : value;
6504 data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
6506 // Compose partial right arguments.
6510 data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
6511 data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
6513 // Use source `argPos` if available.
6518 // Use source `ary` if it's smaller.
6519 if (srcBitmask & WRAP_ARY_FLAG) {
6520 data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
6522 // Use source `arity` if one is not provided.
6523 if (data[9] == null) {
6524 data[9] = source[9];
6526 // Use source `func` and merge bitmasks.
6527 data[0] = source[0];
6528 data[1] = newBitmask;
6534 * Used by `_.defaultsDeep` to customize its `_.merge` use.
6537 * @param {*} objValue The destination value.
6538 * @param {*} srcValue The source value.
6539 * @param {string} key The key of the property to merge.
6540 * @param {Object} object The parent object of `objValue`.
6541 * @param {Object} source The parent object of `srcValue`.
6542 * @param {Object} [stack] Tracks traversed source values and their merged
6544 * @returns {*} Returns the value to assign.
6546 function mergeDefaults(objValue, srcValue, key, object, source, stack) {
6547 if (isObject(objValue) && isObject(srcValue)) {
6548 // Recursively merge objects and arrays (susceptible to call stack limits).
6549 stack.set(srcValue, objValue);
6550 baseMerge(objValue, srcValue, undefined, mergeDefaults, stack);
6551 stack['delete'](srcValue);
6557 * This function is like
6558 * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
6559 * except that it includes inherited enumerable properties.
6562 * @param {Object} object The object to query.
6563 * @returns {Array} Returns the array of property names.
6565 function nativeKeysIn(object) {
6567 if (object != null) {
6568 for (var key in Object(object)) {
6576 * Converts `value` to a string using `Object.prototype.toString`.
6579 * @param {*} value The value to convert.
6580 * @returns {string} Returns the converted string.
6582 function objectToString(value) {
6583 return nativeObjectToString.call(value);
6587 * A specialized version of `baseRest` which transforms the rest array.
6590 * @param {Function} func The function to apply a rest parameter to.
6591 * @param {number} [start=func.length-1] The start position of the rest parameter.
6592 * @param {Function} transform The rest array transform.
6593 * @returns {Function} Returns the new function.
6595 function overRest(func, start, transform) {
6596 start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
6598 var args = arguments,
6600 length = nativeMax(args.length - start, 0),
6601 array = Array(length);
6603 while (++index < length) {
6604 array[index] = args[start + index];
6607 var otherArgs = Array(start + 1);
6608 while (++index < start) {
6609 otherArgs[index] = args[index];
6611 otherArgs[start] = transform(array);
6612 return apply(func, this, otherArgs);
6617 * Gets the parent value at `path` of `object`.
6620 * @param {Object} object The object to query.
6621 * @param {Array} path The path to get the parent value of.
6622 * @returns {*} Returns the parent value.
6624 function parent(object, path) {
6625 return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
6629 * Reorder `array` according to the specified indexes where the element at
6630 * the first index is assigned as the first element, the element at
6631 * the second index is assigned as the second element, and so on.
6634 * @param {Array} array The array to reorder.
6635 * @param {Array} indexes The arranged array indexes.
6636 * @returns {Array} Returns `array`.
6638 function reorder(array, indexes) {
6639 var arrLength = array.length,
6640 length = nativeMin(indexes.length, arrLength),
6641 oldArray = copyArray(array);
6644 var index = indexes[length];
6645 array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
6651 * Sets metadata for `func`.
6653 * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
6654 * period of time, it will trip its breaker and transition to an identity
6655 * function to avoid garbage collection pauses in V8. See
6656 * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
6660 * @param {Function} func The function to associate metadata with.
6661 * @param {*} data The metadata.
6662 * @returns {Function} Returns `func`.
6664 var setData = shortOut(baseSetData);
6667 * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
6670 * @param {Function} func The function to delay.
6671 * @param {number} wait The number of milliseconds to delay invocation.
6672 * @returns {number|Object} Returns the timer id or timeout object.
6674 var setTimeout = ctxSetTimeout || function(func, wait) {
6675 return root.setTimeout(func, wait);
6679 * Sets the `toString` method of `func` to return `string`.
6682 * @param {Function} func The function to modify.
6683 * @param {Function} string The `toString` result.
6684 * @returns {Function} Returns `func`.
6686 var setToString = shortOut(baseSetToString);
6689 * Sets the `toString` method of `wrapper` to mimic the source of `reference`
6690 * with wrapper details in a comment at the top of the source body.
6693 * @param {Function} wrapper The function to modify.
6694 * @param {Function} reference The reference function.
6695 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6696 * @returns {Function} Returns `wrapper`.
6698 function setWrapToString(wrapper, reference, bitmask) {
6699 var source = (reference + '');
6700 return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
6704 * Creates a function that'll short out and invoke `identity` instead
6705 * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
6709 * @param {Function} func The function to restrict.
6710 * @returns {Function} Returns the new shortable function.
6712 function shortOut(func) {
6717 var stamp = nativeNow(),
6718 remaining = HOT_SPAN - (stamp - lastCalled);
6721 if (remaining > 0) {
6722 if (++count >= HOT_COUNT) {
6723 return arguments[0];
6728 return func.apply(undefined, arguments);
6733 * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
6736 * @param {Array} array The array to shuffle.
6737 * @param {number} [size=array.length] The size of `array`.
6738 * @returns {Array} Returns `array`.
6740 function shuffleSelf(array, size) {
6742 length = array.length,
6743 lastIndex = length - 1;
6745 size = size === undefined ? length : size;
6746 while (++index < size) {
6747 var rand = baseRandom(index, lastIndex),
6748 value = array[rand];
6750 array[rand] = array[index];
6751 array[index] = value;
6753 array.length = size;
6758 * Converts `string` to a property path array.
6761 * @param {string} string The string to convert.
6762 * @returns {Array} Returns the property path array.
6764 var stringToPath = memoizeCapped(function(string) {
6766 if (reLeadingDot.test(string)) {
6769 string.replace(rePropName, function(match, number, quote, string) {
6770 result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
6776 * Converts `value` to a string key if it's not a string or symbol.
6779 * @param {*} value The value to inspect.
6780 * @returns {string|symbol} Returns the key.
6782 function toKey(value) {
6783 if (typeof value == 'string' || isSymbol(value)) {
6786 var result = (value + '');
6787 return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
6791 * Converts `func` to its source code.
6794 * @param {Function} func The function to convert.
6795 * @returns {string} Returns the source code.
6797 function toSource(func) {
6800 return funcToString.call(func);
6810 * Updates wrapper `details` based on `bitmask` flags.
6813 * @returns {Array} details The details to modify.
6814 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6815 * @returns {Array} Returns `details`.
6817 function updateWrapDetails(details, bitmask) {
6818 arrayEach(wrapFlags, function(pair) {
6819 var value = '_.' + pair[0];
6820 if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
6821 details.push(value);
6824 return details.sort();
6828 * Creates a clone of `wrapper`.
6831 * @param {Object} wrapper The wrapper to clone.
6832 * @returns {Object} Returns the cloned wrapper.
6834 function wrapperClone(wrapper) {
6835 if (wrapper instanceof LazyWrapper) {
6836 return wrapper.clone();
6838 var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
6839 result.__actions__ = copyArray(wrapper.__actions__);
6840 result.__index__ = wrapper.__index__;
6841 result.__values__ = wrapper.__values__;
6845 /*------------------------------------------------------------------------*/
6848 * Creates an array of elements split into groups the length of `size`.
6849 * If `array` can't be split evenly, the final chunk will be the remaining
6856 * @param {Array} array The array to process.
6857 * @param {number} [size=1] The length of each chunk
6858 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
6859 * @returns {Array} Returns the new array of chunks.
6862 * _.chunk(['a', 'b', 'c', 'd'], 2);
6863 * // => [['a', 'b'], ['c', 'd']]
6865 * _.chunk(['a', 'b', 'c', 'd'], 3);
6866 * // => [['a', 'b', 'c'], ['d']]
6868 function chunk(array, size, guard) {
6869 if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
6872 size = nativeMax(toInteger(size), 0);
6874 var length = array == null ? 0 : array.length;
6875 if (!length || size < 1) {
6880 result = Array(nativeCeil(length / size));
6882 while (index < length) {
6883 result[resIndex++] = baseSlice(array, index, (index += size));
6889 * Creates an array with all falsey values removed. The values `false`, `null`,
6890 * `0`, `""`, `undefined`, and `NaN` are falsey.
6896 * @param {Array} array The array to compact.
6897 * @returns {Array} Returns the new array of filtered values.
6900 * _.compact([0, 1, false, 2, '', 3]);
6903 function compact(array) {
6905 length = array == null ? 0 : array.length,
6909 while (++index < length) {
6910 var value = array[index];
6912 result[resIndex++] = value;
6919 * Creates a new array concatenating `array` with any additional arrays
6926 * @param {Array} array The array to concatenate.
6927 * @param {...*} [values] The values to concatenate.
6928 * @returns {Array} Returns the new concatenated array.
6932 * var other = _.concat(array, 2, [3], [[4]]);
6934 * console.log(other);
6935 * // => [1, 2, 3, [4]]
6937 * console.log(array);
6941 var length = arguments.length;
6945 var args = Array(length - 1),
6946 array = arguments[0],
6950 args[index - 1] = arguments[index];
6952 return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
6956 * Creates an array of `array` values not included in the other given arrays
6957 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
6958 * for equality comparisons. The order and references of result values are
6959 * determined by the first array.
6961 * **Note:** Unlike `_.pullAll`, this method returns a new array.
6967 * @param {Array} array The array to inspect.
6968 * @param {...Array} [values] The values to exclude.
6969 * @returns {Array} Returns the new array of filtered values.
6970 * @see _.without, _.xor
6973 * _.difference([2, 1], [2, 3]);
6976 var difference = baseRest(function(array, values) {
6977 return isArrayLikeObject(array)
6978 ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
6983 * This method is like `_.difference` except that it accepts `iteratee` which
6984 * is invoked for each element of `array` and `values` to generate the criterion
6985 * by which they're compared. The order and references of result values are
6986 * determined by the first array. The iteratee is invoked with one argument:
6989 * **Note:** Unlike `_.pullAllBy`, this method returns a new array.
6995 * @param {Array} array The array to inspect.
6996 * @param {...Array} [values] The values to exclude.
6997 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
6998 * @returns {Array} Returns the new array of filtered values.
7001 * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
7004 * // The `_.property` iteratee shorthand.
7005 * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
7006 * // => [{ 'x': 2 }]
7008 var differenceBy = baseRest(function(array, values) {
7009 var iteratee = last(values);
7010 if (isArrayLikeObject(iteratee)) {
7011 iteratee = undefined;
7013 return isArrayLikeObject(array)
7014 ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
7019 * This method is like `_.difference` except that it accepts `comparator`
7020 * which is invoked to compare elements of `array` to `values`. The order and
7021 * references of result values are determined by the first array. The comparator
7022 * is invoked with two arguments: (arrVal, othVal).
7024 * **Note:** Unlike `_.pullAllWith`, this method returns a new array.
7030 * @param {Array} array The array to inspect.
7031 * @param {...Array} [values] The values to exclude.
7032 * @param {Function} [comparator] The comparator invoked per element.
7033 * @returns {Array} Returns the new array of filtered values.
7036 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7038 * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
7039 * // => [{ 'x': 2, 'y': 1 }]
7041 var differenceWith = baseRest(function(array, values) {
7042 var comparator = last(values);
7043 if (isArrayLikeObject(comparator)) {
7044 comparator = undefined;
7046 return isArrayLikeObject(array)
7047 ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
7052 * Creates a slice of `array` with `n` elements dropped from the beginning.
7058 * @param {Array} array The array to query.
7059 * @param {number} [n=1] The number of elements to drop.
7060 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
7061 * @returns {Array} Returns the slice of `array`.
7064 * _.drop([1, 2, 3]);
7067 * _.drop([1, 2, 3], 2);
7070 * _.drop([1, 2, 3], 5);
7073 * _.drop([1, 2, 3], 0);
7076 function drop(array, n, guard) {
7077 var length = array == null ? 0 : array.length;
7081 n = (guard || n === undefined) ? 1 : toInteger(n);
7082 return baseSlice(array, n < 0 ? 0 : n, length);
7086 * Creates a slice of `array` with `n` elements dropped from the end.
7092 * @param {Array} array The array to query.
7093 * @param {number} [n=1] The number of elements to drop.
7094 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
7095 * @returns {Array} Returns the slice of `array`.
7098 * _.dropRight([1, 2, 3]);
7101 * _.dropRight([1, 2, 3], 2);
7104 * _.dropRight([1, 2, 3], 5);
7107 * _.dropRight([1, 2, 3], 0);
7110 function dropRight(array, n, guard) {
7111 var length = array == null ? 0 : array.length;
7115 n = (guard || n === undefined) ? 1 : toInteger(n);
7117 return baseSlice(array, 0, n < 0 ? 0 : n);
7121 * Creates a slice of `array` excluding elements dropped from the end.
7122 * Elements are dropped until `predicate` returns falsey. The predicate is
7123 * invoked with three arguments: (value, index, array).
7129 * @param {Array} array The array to query.
7130 * @param {Function} [predicate=_.identity] The function invoked per iteration.
7131 * @returns {Array} Returns the slice of `array`.
7135 * { 'user': 'barney', 'active': true },
7136 * { 'user': 'fred', 'active': false },
7137 * { 'user': 'pebbles', 'active': false }
7140 * _.dropRightWhile(users, function(o) { return !o.active; });
7141 * // => objects for ['barney']
7143 * // The `_.matches` iteratee shorthand.
7144 * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
7145 * // => objects for ['barney', 'fred']
7147 * // The `_.matchesProperty` iteratee shorthand.
7148 * _.dropRightWhile(users, ['active', false]);
7149 * // => objects for ['barney']
7151 * // The `_.property` iteratee shorthand.
7152 * _.dropRightWhile(users, 'active');
7153 * // => objects for ['barney', 'fred', 'pebbles']
7155 function dropRightWhile(array, predicate) {
7156 return (array && array.length)
7157 ? baseWhile(array, getIteratee(predicate, 3), true, true)
7162 * Creates a slice of `array` excluding elements dropped from the beginning.
7163 * Elements are dropped until `predicate` returns falsey. The predicate is
7164 * invoked with three arguments: (value, index, array).
7170 * @param {Array} array The array to query.
7171 * @param {Function} [predicate=_.identity] The function invoked per iteration.
7172 * @returns {Array} Returns the slice of `array`.
7176 * { 'user': 'barney', 'active': false },
7177 * { 'user': 'fred', 'active': false },
7178 * { 'user': 'pebbles', 'active': true }
7181 * _.dropWhile(users, function(o) { return !o.active; });
7182 * // => objects for ['pebbles']
7184 * // The `_.matches` iteratee shorthand.
7185 * _.dropWhile(users, { 'user': 'barney', 'active': false });
7186 * // => objects for ['fred', 'pebbles']
7188 * // The `_.matchesProperty` iteratee shorthand.
7189 * _.dropWhile(users, ['active', false]);
7190 * // => objects for ['pebbles']
7192 * // The `_.property` iteratee shorthand.
7193 * _.dropWhile(users, 'active');
7194 * // => objects for ['barney', 'fred', 'pebbles']
7196 function dropWhile(array, predicate) {
7197 return (array && array.length)
7198 ? baseWhile(array, getIteratee(predicate, 3), true)
7203 * Fills elements of `array` with `value` from `start` up to, but not
7206 * **Note:** This method mutates `array`.
7212 * @param {Array} array The array to fill.
7213 * @param {*} value The value to fill `array` with.
7214 * @param {number} [start=0] The start position.
7215 * @param {number} [end=array.length] The end position.
7216 * @returns {Array} Returns `array`.
7219 * var array = [1, 2, 3];
7221 * _.fill(array, 'a');
7222 * console.log(array);
7223 * // => ['a', 'a', 'a']
7225 * _.fill(Array(3), 2);
7228 * _.fill([4, 6, 8, 10], '*', 1, 3);
7229 * // => [4, '*', '*', 10]
7231 function fill(array, value, start, end) {
7232 var length = array == null ? 0 : array.length;
7236 if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
7240 return baseFill(array, value, start, end);
7244 * This method is like `_.find` except that it returns the index of the first
7245 * element `predicate` returns truthy for instead of the element itself.
7251 * @param {Array} array The array to inspect.
7252 * @param {Function} [predicate=_.identity] The function invoked per iteration.
7253 * @param {number} [fromIndex=0] The index to search from.
7254 * @returns {number} Returns the index of the found element, else `-1`.
7258 * { 'user': 'barney', 'active': false },
7259 * { 'user': 'fred', 'active': false },
7260 * { 'user': 'pebbles', 'active': true }
7263 * _.findIndex(users, function(o) { return o.user == 'barney'; });
7266 * // The `_.matches` iteratee shorthand.
7267 * _.findIndex(users, { 'user': 'fred', 'active': false });
7270 * // The `_.matchesProperty` iteratee shorthand.
7271 * _.findIndex(users, ['active', false]);
7274 * // The `_.property` iteratee shorthand.
7275 * _.findIndex(users, 'active');
7278 function findIndex(array, predicate, fromIndex) {
7279 var length = array == null ? 0 : array.length;
7283 var index = fromIndex == null ? 0 : toInteger(fromIndex);
7285 index = nativeMax(length + index, 0);
7287 return baseFindIndex(array, getIteratee(predicate, 3), index);
7291 * This method is like `_.findIndex` except that it iterates over elements
7292 * of `collection` from right to left.
7298 * @param {Array} array The array to inspect.
7299 * @param {Function} [predicate=_.identity] The function invoked per iteration.
7300 * @param {number} [fromIndex=array.length-1] The index to search from.
7301 * @returns {number} Returns the index of the found element, else `-1`.
7305 * { 'user': 'barney', 'active': true },
7306 * { 'user': 'fred', 'active': false },
7307 * { 'user': 'pebbles', 'active': false }
7310 * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
7313 * // The `_.matches` iteratee shorthand.
7314 * _.findLastIndex(users, { 'user': 'barney', 'active': true });
7317 * // The `_.matchesProperty` iteratee shorthand.
7318 * _.findLastIndex(users, ['active', false]);
7321 * // The `_.property` iteratee shorthand.
7322 * _.findLastIndex(users, 'active');
7325 function findLastIndex(array, predicate, fromIndex) {
7326 var length = array == null ? 0 : array.length;
7330 var index = length - 1;
7331 if (fromIndex !== undefined) {
7332 index = toInteger(fromIndex);
7333 index = fromIndex < 0
7334 ? nativeMax(length + index, 0)
7335 : nativeMin(index, length - 1);
7337 return baseFindIndex(array, getIteratee(predicate, 3), index, true);
7341 * Flattens `array` a single level deep.
7347 * @param {Array} array The array to flatten.
7348 * @returns {Array} Returns the new flattened array.
7351 * _.flatten([1, [2, [3, [4]], 5]]);
7352 * // => [1, 2, [3, [4]], 5]
7354 function flatten(array) {
7355 var length = array == null ? 0 : array.length;
7356 return length ? baseFlatten(array, 1) : [];
7360 * Recursively flattens `array`.
7366 * @param {Array} array The array to flatten.
7367 * @returns {Array} Returns the new flattened array.
7370 * _.flattenDeep([1, [2, [3, [4]], 5]]);
7371 * // => [1, 2, 3, 4, 5]
7373 function flattenDeep(array) {
7374 var length = array == null ? 0 : array.length;
7375 return length ? baseFlatten(array, INFINITY) : [];
7379 * Recursively flatten `array` up to `depth` times.
7385 * @param {Array} array The array to flatten.
7386 * @param {number} [depth=1] The maximum recursion depth.
7387 * @returns {Array} Returns the new flattened array.
7390 * var array = [1, [2, [3, [4]], 5]];
7392 * _.flattenDepth(array, 1);
7393 * // => [1, 2, [3, [4]], 5]
7395 * _.flattenDepth(array, 2);
7396 * // => [1, 2, 3, [4], 5]
7398 function flattenDepth(array, depth) {
7399 var length = array == null ? 0 : array.length;
7403 depth = depth === undefined ? 1 : toInteger(depth);
7404 return baseFlatten(array, depth);
7408 * The inverse of `_.toPairs`; this method returns an object composed
7409 * from key-value `pairs`.
7415 * @param {Array} pairs The key-value pairs.
7416 * @returns {Object} Returns the new object.
7419 * _.fromPairs([['a', 1], ['b', 2]]);
7420 * // => { 'a': 1, 'b': 2 }
7422 function fromPairs(pairs) {
7424 length = pairs == null ? 0 : pairs.length,
7427 while (++index < length) {
7428 var pair = pairs[index];
7429 result[pair[0]] = pair[1];
7435 * Gets the first element of `array`.
7442 * @param {Array} array The array to query.
7443 * @returns {*} Returns the first element of `array`.
7446 * _.head([1, 2, 3]);
7452 function head(array) {
7453 return (array && array.length) ? array[0] : undefined;
7457 * Gets the index at which the first occurrence of `value` is found in `array`
7458 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
7459 * for equality comparisons. If `fromIndex` is negative, it's used as the
7460 * offset from the end of `array`.
7466 * @param {Array} array The array to inspect.
7467 * @param {*} value The value to search for.
7468 * @param {number} [fromIndex=0] The index to search from.
7469 * @returns {number} Returns the index of the matched value, else `-1`.
7472 * _.indexOf([1, 2, 1, 2], 2);
7475 * // Search from the `fromIndex`.
7476 * _.indexOf([1, 2, 1, 2], 2, 2);
7479 function indexOf(array, value, fromIndex) {
7480 var length = array == null ? 0 : array.length;
7484 var index = fromIndex == null ? 0 : toInteger(fromIndex);
7486 index = nativeMax(length + index, 0);
7488 return baseIndexOf(array, value, index);
7492 * Gets all but the last element of `array`.
7498 * @param {Array} array The array to query.
7499 * @returns {Array} Returns the slice of `array`.
7502 * _.initial([1, 2, 3]);
7505 function initial(array) {
7506 var length = array == null ? 0 : array.length;
7507 return length ? baseSlice(array, 0, -1) : [];
7511 * Creates an array of unique values that are included in all given arrays
7512 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
7513 * for equality comparisons. The order and references of result values are
7514 * determined by the first array.
7520 * @param {...Array} [arrays] The arrays to inspect.
7521 * @returns {Array} Returns the new array of intersecting values.
7524 * _.intersection([2, 1], [2, 3]);
7527 var intersection = baseRest(function(arrays) {
7528 var mapped = arrayMap(arrays, castArrayLikeObject);
7529 return (mapped.length && mapped[0] === arrays[0])
7530 ? baseIntersection(mapped)
7535 * This method is like `_.intersection` except that it accepts `iteratee`
7536 * which is invoked for each element of each `arrays` to generate the criterion
7537 * by which they're compared. The order and references of result values are
7538 * determined by the first array. The iteratee is invoked with one argument:
7545 * @param {...Array} [arrays] The arrays to inspect.
7546 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7547 * @returns {Array} Returns the new array of intersecting values.
7550 * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
7553 * // The `_.property` iteratee shorthand.
7554 * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
7555 * // => [{ 'x': 1 }]
7557 var intersectionBy = baseRest(function(arrays) {
7558 var iteratee = last(arrays),
7559 mapped = arrayMap(arrays, castArrayLikeObject);
7561 if (iteratee === last(mapped)) {
7562 iteratee = undefined;
7566 return (mapped.length && mapped[0] === arrays[0])
7567 ? baseIntersection(mapped, getIteratee(iteratee, 2))
7572 * This method is like `_.intersection` except that it accepts `comparator`
7573 * which is invoked to compare elements of `arrays`. The order and references
7574 * of result values are determined by the first array. The comparator is
7575 * invoked with two arguments: (arrVal, othVal).
7581 * @param {...Array} [arrays] The arrays to inspect.
7582 * @param {Function} [comparator] The comparator invoked per element.
7583 * @returns {Array} Returns the new array of intersecting values.
7586 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7587 * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
7589 * _.intersectionWith(objects, others, _.isEqual);
7590 * // => [{ 'x': 1, 'y': 2 }]
7592 var intersectionWith = baseRest(function(arrays) {
7593 var comparator = last(arrays),
7594 mapped = arrayMap(arrays, castArrayLikeObject);
7596 comparator = typeof comparator == 'function' ? comparator : undefined;
7600 return (mapped.length && mapped[0] === arrays[0])
7601 ? baseIntersection(mapped, undefined, comparator)
7606 * Converts all elements in `array` into a string separated by `separator`.
7612 * @param {Array} array The array to convert.
7613 * @param {string} [separator=','] The element separator.
7614 * @returns {string} Returns the joined string.
7617 * _.join(['a', 'b', 'c'], '~');
7620 function join(array, separator) {
7621 return array == null ? '' : nativeJoin.call(array, separator);
7625 * Gets the last element of `array`.
7631 * @param {Array} array The array to query.
7632 * @returns {*} Returns the last element of `array`.
7635 * _.last([1, 2, 3]);
7638 function last(array) {
7639 var length = array == null ? 0 : array.length;
7640 return length ? array[length - 1] : undefined;
7644 * This method is like `_.indexOf` except that it iterates over elements of
7645 * `array` from right to left.
7651 * @param {Array} array The array to inspect.
7652 * @param {*} value The value to search for.
7653 * @param {number} [fromIndex=array.length-1] The index to search from.
7654 * @returns {number} Returns the index of the matched value, else `-1`.
7657 * _.lastIndexOf([1, 2, 1, 2], 2);
7660 * // Search from the `fromIndex`.
7661 * _.lastIndexOf([1, 2, 1, 2], 2, 2);
7664 function lastIndexOf(array, value, fromIndex) {
7665 var length = array == null ? 0 : array.length;
7670 if (fromIndex !== undefined) {
7671 index = toInteger(fromIndex);
7672 index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
7674 return value === value
7675 ? strictLastIndexOf(array, value, index)
7676 : baseFindIndex(array, baseIsNaN, index, true);
7680 * Gets the element at index `n` of `array`. If `n` is negative, the nth
7681 * element from the end is returned.
7687 * @param {Array} array The array to query.
7688 * @param {number} [n=0] The index of the element to return.
7689 * @returns {*} Returns the nth element of `array`.
7692 * var array = ['a', 'b', 'c', 'd'];
7700 function nth(array, n) {
7701 return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
7705 * Removes all given values from `array` using
7706 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
7707 * for equality comparisons.
7709 * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
7710 * to remove elements from an array by predicate.
7716 * @param {Array} array The array to modify.
7717 * @param {...*} [values] The values to remove.
7718 * @returns {Array} Returns `array`.
7721 * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
7723 * _.pull(array, 'a', 'c');
7724 * console.log(array);
7727 var pull = baseRest(pullAll);
7730 * This method is like `_.pull` except that it accepts an array of values to remove.
7732 * **Note:** Unlike `_.difference`, this method mutates `array`.
7738 * @param {Array} array The array to modify.
7739 * @param {Array} values The values to remove.
7740 * @returns {Array} Returns `array`.
7743 * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
7745 * _.pullAll(array, ['a', 'c']);
7746 * console.log(array);
7749 function pullAll(array, values) {
7750 return (array && array.length && values && values.length)
7751 ? basePullAll(array, values)
7756 * This method is like `_.pullAll` except that it accepts `iteratee` which is
7757 * invoked for each element of `array` and `values` to generate the criterion
7758 * by which they're compared. The iteratee is invoked with one argument: (value).
7760 * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
7766 * @param {Array} array The array to modify.
7767 * @param {Array} values The values to remove.
7768 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7769 * @returns {Array} Returns `array`.
7772 * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
7774 * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
7775 * console.log(array);
7776 * // => [{ 'x': 2 }]
7778 function pullAllBy(array, values, iteratee) {
7779 return (array && array.length && values && values.length)
7780 ? basePullAll(array, values, getIteratee(iteratee, 2))
7785 * This method is like `_.pullAll` except that it accepts `comparator` which
7786 * is invoked to compare elements of `array` to `values`. The comparator is
7787 * invoked with two arguments: (arrVal, othVal).
7789 * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
7795 * @param {Array} array The array to modify.
7796 * @param {Array} values The values to remove.
7797 * @param {Function} [comparator] The comparator invoked per element.
7798 * @returns {Array} Returns `array`.
7801 * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
7803 * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
7804 * console.log(array);
7805 * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
7807 function pullAllWith(array, values, comparator) {
7808 return (array && array.length && values && values.length)
7809 ? basePullAll(array, values, undefined, comparator)
7814 * Removes elements from `array` corresponding to `indexes` and returns an
7815 * array of removed elements.
7817 * **Note:** Unlike `_.at`, this method mutates `array`.
7823 * @param {Array} array The array to modify.
7824 * @param {...(number|number[])} [indexes] The indexes of elements to remove.
7825 * @returns {Array} Returns the new array of removed elements.
7828 * var array = ['a', 'b', 'c', 'd'];
7829 * var pulled = _.pullAt(array, [1, 3]);
7831 * console.log(array);
7834 * console.log(pulled);
7837 var pullAt = flatRest(function(array, indexes) {
7838 var length = array == null ? 0 : array.length,
7839 result = baseAt(array, indexes);
7841 basePullAt(array, arrayMap(indexes, function(index) {
7842 return isIndex(index, length) ? +index : index;
7843 }).sort(compareAscending));
7849 * Removes all elements from `array` that `predicate` returns truthy for
7850 * and returns an array of the removed elements. The predicate is invoked
7851 * with three arguments: (value, index, array).
7853 * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
7854 * to pull elements from an array by value.
7860 * @param {Array} array The array to modify.
7861 * @param {Function} [predicate=_.identity] The function invoked per iteration.
7862 * @returns {Array} Returns the new array of removed elements.
7865 * var array = [1, 2, 3, 4];
7866 * var evens = _.remove(array, function(n) {
7867 * return n % 2 == 0;
7870 * console.log(array);
7873 * console.log(evens);
7876 function remove(array, predicate) {
7878 if (!(array && array.length)) {
7883 length = array.length;
7885 predicate = getIteratee(predicate, 3);
7886 while (++index < length) {
7887 var value = array[index];
7888 if (predicate(value, index, array)) {
7890 indexes.push(index);
7893 basePullAt(array, indexes);
7898 * Reverses `array` so that the first element becomes the last, the second
7899 * element becomes the second to last, and so on.
7901 * **Note:** This method mutates `array` and is based on
7902 * [`Array#reverse`](https://mdn.io/Array/reverse).
7908 * @param {Array} array The array to modify.
7909 * @returns {Array} Returns `array`.
7912 * var array = [1, 2, 3];
7917 * console.log(array);
7920 function reverse(array) {
7921 return array == null ? array : nativeReverse.call(array);
7925 * Creates a slice of `array` from `start` up to, but not including, `end`.
7927 * **Note:** This method is used instead of
7928 * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
7935 * @param {Array} array The array to slice.
7936 * @param {number} [start=0] The start position.
7937 * @param {number} [end=array.length] The end position.
7938 * @returns {Array} Returns the slice of `array`.
7940 function slice(array, start, end) {
7941 var length = array == null ? 0 : array.length;
7945 if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
7950 start = start == null ? 0 : toInteger(start);
7951 end = end === undefined ? length : toInteger(end);
7953 return baseSlice(array, start, end);
7957 * Uses a binary search to determine the lowest index at which `value`
7958 * should be inserted into `array` in order to maintain its sort order.
7964 * @param {Array} array The sorted array to inspect.
7965 * @param {*} value The value to evaluate.
7966 * @returns {number} Returns the index at which `value` should be inserted
7970 * _.sortedIndex([30, 50], 40);
7973 function sortedIndex(array, value) {
7974 return baseSortedIndex(array, value);
7978 * This method is like `_.sortedIndex` except that it accepts `iteratee`
7979 * which is invoked for `value` and each element of `array` to compute their
7980 * sort ranking. The iteratee is invoked with one argument: (value).
7986 * @param {Array} array The sorted array to inspect.
7987 * @param {*} value The value to evaluate.
7988 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7989 * @returns {number} Returns the index at which `value` should be inserted
7993 * var objects = [{ 'x': 4 }, { 'x': 5 }];
7995 * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
7998 * // The `_.property` iteratee shorthand.
7999 * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
8002 function sortedIndexBy(array, value, iteratee) {
8003 return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
8007 * This method is like `_.indexOf` except that it performs a binary
8008 * search on a sorted `array`.
8014 * @param {Array} array The array to inspect.
8015 * @param {*} value The value to search for.
8016 * @returns {number} Returns the index of the matched value, else `-1`.
8019 * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
8022 function sortedIndexOf(array, value) {
8023 var length = array == null ? 0 : array.length;
8025 var index = baseSortedIndex(array, value);
8026 if (index < length && eq(array[index], value)) {
8034 * This method is like `_.sortedIndex` except that it returns the highest
8035 * index at which `value` should be inserted into `array` in order to
8036 * maintain its sort order.
8042 * @param {Array} array The sorted array to inspect.
8043 * @param {*} value The value to evaluate.
8044 * @returns {number} Returns the index at which `value` should be inserted
8048 * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
8051 function sortedLastIndex(array, value) {
8052 return baseSortedIndex(array, value, true);
8056 * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
8057 * which is invoked for `value` and each element of `array` to compute their
8058 * sort ranking. The iteratee is invoked with one argument: (value).
8064 * @param {Array} array The sorted array to inspect.
8065 * @param {*} value The value to evaluate.
8066 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8067 * @returns {number} Returns the index at which `value` should be inserted
8071 * var objects = [{ 'x': 4 }, { 'x': 5 }];
8073 * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
8076 * // The `_.property` iteratee shorthand.
8077 * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
8080 function sortedLastIndexBy(array, value, iteratee) {
8081 return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
8085 * This method is like `_.lastIndexOf` except that it performs a binary
8086 * search on a sorted `array`.
8092 * @param {Array} array The array to inspect.
8093 * @param {*} value The value to search for.
8094 * @returns {number} Returns the index of the matched value, else `-1`.
8097 * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
8100 function sortedLastIndexOf(array, value) {
8101 var length = array == null ? 0 : array.length;
8103 var index = baseSortedIndex(array, value, true) - 1;
8104 if (eq(array[index], value)) {
8112 * This method is like `_.uniq` except that it's designed and optimized
8113 * for sorted arrays.
8119 * @param {Array} array The array to inspect.
8120 * @returns {Array} Returns the new duplicate free array.
8123 * _.sortedUniq([1, 1, 2]);
8126 function sortedUniq(array) {
8127 return (array && array.length)
8128 ? baseSortedUniq(array)
8133 * This method is like `_.uniqBy` except that it's designed and optimized
8134 * for sorted arrays.
8140 * @param {Array} array The array to inspect.
8141 * @param {Function} [iteratee] The iteratee invoked per element.
8142 * @returns {Array} Returns the new duplicate free array.
8145 * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
8148 function sortedUniqBy(array, iteratee) {
8149 return (array && array.length)
8150 ? baseSortedUniq(array, getIteratee(iteratee, 2))
8155 * Gets all but the first element of `array`.
8161 * @param {Array} array The array to query.
8162 * @returns {Array} Returns the slice of `array`.
8165 * _.tail([1, 2, 3]);
8168 function tail(array) {
8169 var length = array == null ? 0 : array.length;
8170 return length ? baseSlice(array, 1, length) : [];
8174 * Creates a slice of `array` with `n` elements taken from the beginning.
8180 * @param {Array} array The array to query.
8181 * @param {number} [n=1] The number of elements to take.
8182 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8183 * @returns {Array} Returns the slice of `array`.
8186 * _.take([1, 2, 3]);
8189 * _.take([1, 2, 3], 2);
8192 * _.take([1, 2, 3], 5);
8195 * _.take([1, 2, 3], 0);
8198 function take(array, n, guard) {
8199 if (!(array && array.length)) {
8202 n = (guard || n === undefined) ? 1 : toInteger(n);
8203 return baseSlice(array, 0, n < 0 ? 0 : n);
8207 * Creates a slice of `array` with `n` elements taken from the end.
8213 * @param {Array} array The array to query.
8214 * @param {number} [n=1] The number of elements to take.
8215 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8216 * @returns {Array} Returns the slice of `array`.
8219 * _.takeRight([1, 2, 3]);
8222 * _.takeRight([1, 2, 3], 2);
8225 * _.takeRight([1, 2, 3], 5);
8228 * _.takeRight([1, 2, 3], 0);
8231 function takeRight(array, n, guard) {
8232 var length = array == null ? 0 : array.length;
8236 n = (guard || n === undefined) ? 1 : toInteger(n);
8238 return baseSlice(array, n < 0 ? 0 : n, length);
8242 * Creates a slice of `array` with elements taken from the end. Elements are
8243 * taken until `predicate` returns falsey. The predicate is invoked with
8244 * three arguments: (value, index, array).
8250 * @param {Array} array The array to query.
8251 * @param {Function} [predicate=_.identity] The function invoked per iteration.
8252 * @returns {Array} Returns the slice of `array`.
8256 * { 'user': 'barney', 'active': true },
8257 * { 'user': 'fred', 'active': false },
8258 * { 'user': 'pebbles', 'active': false }
8261 * _.takeRightWhile(users, function(o) { return !o.active; });
8262 * // => objects for ['fred', 'pebbles']
8264 * // The `_.matches` iteratee shorthand.
8265 * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
8266 * // => objects for ['pebbles']
8268 * // The `_.matchesProperty` iteratee shorthand.
8269 * _.takeRightWhile(users, ['active', false]);
8270 * // => objects for ['fred', 'pebbles']
8272 * // The `_.property` iteratee shorthand.
8273 * _.takeRightWhile(users, 'active');
8276 function takeRightWhile(array, predicate) {
8277 return (array && array.length)
8278 ? baseWhile(array, getIteratee(predicate, 3), false, true)
8283 * Creates a slice of `array` with elements taken from the beginning. Elements
8284 * are taken until `predicate` returns falsey. The predicate is invoked with
8285 * three arguments: (value, index, array).
8291 * @param {Array} array The array to query.
8292 * @param {Function} [predicate=_.identity] The function invoked per iteration.
8293 * @returns {Array} Returns the slice of `array`.
8297 * { 'user': 'barney', 'active': false },
8298 * { 'user': 'fred', 'active': false},
8299 * { 'user': 'pebbles', 'active': true }
8302 * _.takeWhile(users, function(o) { return !o.active; });
8303 * // => objects for ['barney', 'fred']
8305 * // The `_.matches` iteratee shorthand.
8306 * _.takeWhile(users, { 'user': 'barney', 'active': false });
8307 * // => objects for ['barney']
8309 * // The `_.matchesProperty` iteratee shorthand.
8310 * _.takeWhile(users, ['active', false]);
8311 * // => objects for ['barney', 'fred']
8313 * // The `_.property` iteratee shorthand.
8314 * _.takeWhile(users, 'active');
8317 function takeWhile(array, predicate) {
8318 return (array && array.length)
8319 ? baseWhile(array, getIteratee(predicate, 3))
8324 * Creates an array of unique values, in order, from all given arrays using
8325 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8326 * for equality comparisons.
8332 * @param {...Array} [arrays] The arrays to inspect.
8333 * @returns {Array} Returns the new array of combined values.
8336 * _.union([2], [1, 2]);
8339 var union = baseRest(function(arrays) {
8340 return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
8344 * This method is like `_.union` except that it accepts `iteratee` which is
8345 * invoked for each element of each `arrays` to generate the criterion by
8346 * which uniqueness is computed. Result values are chosen from the first
8347 * array in which the value occurs. The iteratee is invoked with one argument:
8354 * @param {...Array} [arrays] The arrays to inspect.
8355 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8356 * @returns {Array} Returns the new array of combined values.
8359 * _.unionBy([2.1], [1.2, 2.3], Math.floor);
8362 * // The `_.property` iteratee shorthand.
8363 * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8364 * // => [{ 'x': 1 }, { 'x': 2 }]
8366 var unionBy = baseRest(function(arrays) {
8367 var iteratee = last(arrays);
8368 if (isArrayLikeObject(iteratee)) {
8369 iteratee = undefined;
8371 return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
8375 * This method is like `_.union` except that it accepts `comparator` which
8376 * is invoked to compare elements of `arrays`. Result values are chosen from
8377 * the first array in which the value occurs. The comparator is invoked
8378 * with two arguments: (arrVal, othVal).
8384 * @param {...Array} [arrays] The arrays to inspect.
8385 * @param {Function} [comparator] The comparator invoked per element.
8386 * @returns {Array} Returns the new array of combined values.
8389 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
8390 * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
8392 * _.unionWith(objects, others, _.isEqual);
8393 * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
8395 var unionWith = baseRest(function(arrays) {
8396 var comparator = last(arrays);
8397 comparator = typeof comparator == 'function' ? comparator : undefined;
8398 return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
8402 * Creates a duplicate-free version of an array, using
8403 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8404 * for equality comparisons, in which only the first occurrence of each element
8405 * is kept. The order of result values is determined by the order they occur
8412 * @param {Array} array The array to inspect.
8413 * @returns {Array} Returns the new duplicate free array.
8416 * _.uniq([2, 1, 2]);
8419 function uniq(array) {
8420 return (array && array.length) ? baseUniq(array) : [];
8424 * This method is like `_.uniq` except that it accepts `iteratee` which is
8425 * invoked for each element in `array` to generate the criterion by which
8426 * uniqueness is computed. The order of result values is determined by the
8427 * order they occur in the array. The iteratee is invoked with one argument:
8434 * @param {Array} array The array to inspect.
8435 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8436 * @returns {Array} Returns the new duplicate free array.
8439 * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
8442 * // The `_.property` iteratee shorthand.
8443 * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
8444 * // => [{ 'x': 1 }, { 'x': 2 }]
8446 function uniqBy(array, iteratee) {
8447 return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
8451 * This method is like `_.uniq` except that it accepts `comparator` which
8452 * is invoked to compare elements of `array`. The order of result values is
8453 * determined by the order they occur in the array.The comparator is invoked
8454 * with two arguments: (arrVal, othVal).
8460 * @param {Array} array The array to inspect.
8461 * @param {Function} [comparator] The comparator invoked per element.
8462 * @returns {Array} Returns the new duplicate free array.
8465 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
8467 * _.uniqWith(objects, _.isEqual);
8468 * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
8470 function uniqWith(array, comparator) {
8471 comparator = typeof comparator == 'function' ? comparator : undefined;
8472 return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
8476 * This method is like `_.zip` except that it accepts an array of grouped
8477 * elements and creates an array regrouping the elements to their pre-zip
8484 * @param {Array} array The array of grouped elements to process.
8485 * @returns {Array} Returns the new array of regrouped elements.
8488 * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
8489 * // => [['a', 1, true], ['b', 2, false]]
8492 * // => [['a', 'b'], [1, 2], [true, false]]
8494 function unzip(array) {
8495 if (!(array && array.length)) {
8499 array = arrayFilter(array, function(group) {
8500 if (isArrayLikeObject(group)) {
8501 length = nativeMax(group.length, length);
8505 return baseTimes(length, function(index) {
8506 return arrayMap(array, baseProperty(index));
8511 * This method is like `_.unzip` except that it accepts `iteratee` to specify
8512 * how regrouped values should be combined. The iteratee is invoked with the
8513 * elements of each group: (...group).
8519 * @param {Array} array The array of grouped elements to process.
8520 * @param {Function} [iteratee=_.identity] The function to combine
8522 * @returns {Array} Returns the new array of regrouped elements.
8525 * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
8526 * // => [[1, 10, 100], [2, 20, 200]]
8528 * _.unzipWith(zipped, _.add);
8529 * // => [3, 30, 300]
8531 function unzipWith(array, iteratee) {
8532 if (!(array && array.length)) {
8535 var result = unzip(array);
8536 if (iteratee == null) {
8539 return arrayMap(result, function(group) {
8540 return apply(iteratee, undefined, group);
8545 * Creates an array excluding all given values using
8546 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8547 * for equality comparisons.
8549 * **Note:** Unlike `_.pull`, this method returns a new array.
8555 * @param {Array} array The array to inspect.
8556 * @param {...*} [values] The values to exclude.
8557 * @returns {Array} Returns the new array of filtered values.
8558 * @see _.difference, _.xor
8561 * _.without([2, 1, 2, 3], 1, 2);
8564 var without = baseRest(function(array, values) {
8565 return isArrayLikeObject(array)
8566 ? baseDifference(array, values)
8571 * Creates an array of unique values that is the
8572 * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
8573 * of the given arrays. The order of result values is determined by the order
8574 * they occur in the arrays.
8580 * @param {...Array} [arrays] The arrays to inspect.
8581 * @returns {Array} Returns the new array of filtered values.
8582 * @see _.difference, _.without
8585 * _.xor([2, 1], [2, 3]);
8588 var xor = baseRest(function(arrays) {
8589 return baseXor(arrayFilter(arrays, isArrayLikeObject));
8593 * This method is like `_.xor` except that it accepts `iteratee` which is
8594 * invoked for each element of each `arrays` to generate the criterion by
8595 * which by which they're compared. The order of result values is determined
8596 * by the order they occur in the arrays. The iteratee is invoked with one
8597 * argument: (value).
8603 * @param {...Array} [arrays] The arrays to inspect.
8604 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8605 * @returns {Array} Returns the new array of filtered values.
8608 * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
8611 * // The `_.property` iteratee shorthand.
8612 * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8613 * // => [{ 'x': 2 }]
8615 var xorBy = baseRest(function(arrays) {
8616 var iteratee = last(arrays);
8617 if (isArrayLikeObject(iteratee)) {
8618 iteratee = undefined;
8620 return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
8624 * This method is like `_.xor` except that it accepts `comparator` which is
8625 * invoked to compare elements of `arrays`. The order of result values is
8626 * determined by the order they occur in the arrays. The comparator is invoked
8627 * with two arguments: (arrVal, othVal).
8633 * @param {...Array} [arrays] The arrays to inspect.
8634 * @param {Function} [comparator] The comparator invoked per element.
8635 * @returns {Array} Returns the new array of filtered values.
8638 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
8639 * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
8641 * _.xorWith(objects, others, _.isEqual);
8642 * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
8644 var xorWith = baseRest(function(arrays) {
8645 var comparator = last(arrays);
8646 comparator = typeof comparator == 'function' ? comparator : undefined;
8647 return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
8651 * Creates an array of grouped elements, the first of which contains the
8652 * first elements of the given arrays, the second of which contains the
8653 * second elements of the given arrays, and so on.
8659 * @param {...Array} [arrays] The arrays to process.
8660 * @returns {Array} Returns the new array of grouped elements.
8663 * _.zip(['a', 'b'], [1, 2], [true, false]);
8664 * // => [['a', 1, true], ['b', 2, false]]
8666 var zip = baseRest(unzip);
8669 * This method is like `_.fromPairs` except that it accepts two arrays,
8670 * one of property identifiers and one of corresponding values.
8676 * @param {Array} [props=[]] The property identifiers.
8677 * @param {Array} [values=[]] The property values.
8678 * @returns {Object} Returns the new object.
8681 * _.zipObject(['a', 'b'], [1, 2]);
8682 * // => { 'a': 1, 'b': 2 }
8684 function zipObject(props, values) {
8685 return baseZipObject(props || [], values || [], assignValue);
8689 * This method is like `_.zipObject` except that it supports property paths.
8695 * @param {Array} [props=[]] The property identifiers.
8696 * @param {Array} [values=[]] The property values.
8697 * @returns {Object} Returns the new object.
8700 * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
8701 * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
8703 function zipObjectDeep(props, values) {
8704 return baseZipObject(props || [], values || [], baseSet);
8708 * This method is like `_.zip` except that it accepts `iteratee` to specify
8709 * how grouped values should be combined. The iteratee is invoked with the
8710 * elements of each group: (...group).
8716 * @param {...Array} [arrays] The arrays to process.
8717 * @param {Function} [iteratee=_.identity] The function to combine
8719 * @returns {Array} Returns the new array of grouped elements.
8722 * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
8727 var zipWith = baseRest(function(arrays) {
8728 var length = arrays.length,
8729 iteratee = length > 1 ? arrays[length - 1] : undefined;
8731 iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
8732 return unzipWith(arrays, iteratee);
8735 /*------------------------------------------------------------------------*/
8738 * Creates a `lodash` wrapper instance that wraps `value` with explicit method
8739 * chain sequences enabled. The result of such sequences must be unwrapped
8746 * @param {*} value The value to wrap.
8747 * @returns {Object} Returns the new `lodash` wrapper instance.
8751 * { 'user': 'barney', 'age': 36 },
8752 * { 'user': 'fred', 'age': 40 },
8753 * { 'user': 'pebbles', 'age': 1 }
8759 * .map(function(o) {
8760 * return o.user + ' is ' + o.age;
8764 * // => 'pebbles is 1'
8766 function chain(value) {
8767 var result = lodash(value);
8768 result.__chain__ = true;
8773 * This method invokes `interceptor` and returns `value`. The interceptor
8774 * is invoked with one argument; (value). The purpose of this method is to
8775 * "tap into" a method chain sequence in order to modify intermediate results.
8781 * @param {*} value The value to provide to `interceptor`.
8782 * @param {Function} interceptor The function to invoke.
8783 * @returns {*} Returns `value`.
8787 * .tap(function(array) {
8788 * // Mutate input array.
8795 function tap(value, interceptor) {
8801 * This method is like `_.tap` except that it returns the result of `interceptor`.
8802 * The purpose of this method is to "pass thru" values replacing intermediate
8803 * results in a method chain sequence.
8809 * @param {*} value The value to provide to `interceptor`.
8810 * @param {Function} interceptor The function to invoke.
8811 * @returns {*} Returns the result of `interceptor`.
8817 * .thru(function(value) {
8823 function thru(value, interceptor) {
8824 return interceptor(value);
8828 * This method is the wrapper version of `_.at`.
8834 * @param {...(string|string[])} [paths] The property paths to pick.
8835 * @returns {Object} Returns the new `lodash` wrapper instance.
8838 * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
8840 * _(object).at(['a[0].b.c', 'a[1]']).value();
8843 var wrapperAt = flatRest(function(paths) {
8844 var length = paths.length,
8845 start = length ? paths[0] : 0,
8846 value = this.__wrapped__,
8847 interceptor = function(object) { return baseAt(object, paths); };
8849 if (length > 1 || this.__actions__.length ||
8850 !(value instanceof LazyWrapper) || !isIndex(start)) {
8851 return this.thru(interceptor);
8853 value = value.slice(start, +start + (length ? 1 : 0));
8854 value.__actions__.push({
8856 'args': [interceptor],
8857 'thisArg': undefined
8859 return new LodashWrapper(value, this.__chain__).thru(function(array) {
8860 if (length && !array.length) {
8861 array.push(undefined);
8868 * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
8874 * @returns {Object} Returns the new `lodash` wrapper instance.
8878 * { 'user': 'barney', 'age': 36 },
8879 * { 'user': 'fred', 'age': 40 }
8882 * // A sequence without explicit chaining.
8884 * // => { 'user': 'barney', 'age': 36 }
8886 * // A sequence with explicit chaining.
8892 * // => { 'user': 'barney' }
8894 function wrapperChain() {
8899 * Executes the chain sequence and returns the wrapped result.
8905 * @returns {Object} Returns the new `lodash` wrapper instance.
8908 * var array = [1, 2];
8909 * var wrapped = _(array).push(3);
8911 * console.log(array);
8914 * wrapped = wrapped.commit();
8915 * console.log(array);
8921 * console.log(array);
8924 function wrapperCommit() {
8925 return new LodashWrapper(this.value(), this.__chain__);
8929 * Gets the next value on a wrapped object following the
8930 * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
8936 * @returns {Object} Returns the next iterator value.
8939 * var wrapped = _([1, 2]);
8942 * // => { 'done': false, 'value': 1 }
8945 * // => { 'done': false, 'value': 2 }
8948 * // => { 'done': true, 'value': undefined }
8950 function wrapperNext() {
8951 if (this.__values__ === undefined) {
8952 this.__values__ = toArray(this.value());
8954 var done = this.__index__ >= this.__values__.length,
8955 value = done ? undefined : this.__values__[this.__index__++];
8957 return { 'done': done, 'value': value };
8961 * Enables the wrapper to be iterable.
8963 * @name Symbol.iterator
8967 * @returns {Object} Returns the wrapper object.
8970 * var wrapped = _([1, 2]);
8972 * wrapped[Symbol.iterator]() === wrapped;
8975 * Array.from(wrapped);
8978 function wrapperToIterator() {
8983 * Creates a clone of the chain sequence planting `value` as the wrapped value.
8989 * @param {*} value The value to plant.
8990 * @returns {Object} Returns the new `lodash` wrapper instance.
8993 * function square(n) {
8997 * var wrapped = _([1, 2]).map(square);
8998 * var other = wrapped.plant([3, 4]);
9006 function wrapperPlant(value) {
9010 while (parent instanceof baseLodash) {
9011 var clone = wrapperClone(parent);
9012 clone.__index__ = 0;
9013 clone.__values__ = undefined;
9015 previous.__wrapped__ = clone;
9019 var previous = clone;
9020 parent = parent.__wrapped__;
9022 previous.__wrapped__ = value;
9027 * This method is the wrapper version of `_.reverse`.
9029 * **Note:** This method mutates the wrapped array.
9035 * @returns {Object} Returns the new `lodash` wrapper instance.
9038 * var array = [1, 2, 3];
9040 * _(array).reverse().value()
9043 * console.log(array);
9046 function wrapperReverse() {
9047 var value = this.__wrapped__;
9048 if (value instanceof LazyWrapper) {
9049 var wrapped = value;
9050 if (this.__actions__.length) {
9051 wrapped = new LazyWrapper(this);
9053 wrapped = wrapped.reverse();
9054 wrapped.__actions__.push({
9057 'thisArg': undefined
9059 return new LodashWrapper(wrapped, this.__chain__);
9061 return this.thru(reverse);
9065 * Executes the chain sequence to resolve the unwrapped value.
9070 * @alias toJSON, valueOf
9072 * @returns {*} Returns the resolved unwrapped value.
9075 * _([1, 2, 3]).value();
9078 function wrapperValue() {
9079 return baseWrapperValue(this.__wrapped__, this.__actions__);
9082 /*------------------------------------------------------------------------*/
9085 * Creates an object composed of keys generated from the results of running
9086 * each element of `collection` thru `iteratee`. The corresponding value of
9087 * each key is the number of times the key was returned by `iteratee`. The
9088 * iteratee is invoked with one argument: (value).
9093 * @category Collection
9094 * @param {Array|Object} collection The collection to iterate over.
9095 * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
9096 * @returns {Object} Returns the composed aggregate object.
9099 * _.countBy([6.1, 4.2, 6.3], Math.floor);
9100 * // => { '4': 1, '6': 2 }
9102 * // The `_.property` iteratee shorthand.
9103 * _.countBy(['one', 'two', 'three'], 'length');
9104 * // => { '3': 2, '5': 1 }
9106 var countBy = createAggregator(function(result, value, key) {
9107 if (hasOwnProperty.call(result, key)) {
9110 baseAssignValue(result, key, 1);
9115 * Checks if `predicate` returns truthy for **all** elements of `collection`.
9116 * Iteration is stopped once `predicate` returns falsey. The predicate is
9117 * invoked with three arguments: (value, index|key, collection).
9119 * **Note:** This method returns `true` for
9120 * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
9121 * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
9122 * elements of empty collections.
9127 * @category Collection
9128 * @param {Array|Object} collection The collection to iterate over.
9129 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9130 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9131 * @returns {boolean} Returns `true` if all elements pass the predicate check,
9135 * _.every([true, 1, null, 'yes'], Boolean);
9139 * { 'user': 'barney', 'age': 36, 'active': false },
9140 * { 'user': 'fred', 'age': 40, 'active': false }
9143 * // The `_.matches` iteratee shorthand.
9144 * _.every(users, { 'user': 'barney', 'active': false });
9147 * // The `_.matchesProperty` iteratee shorthand.
9148 * _.every(users, ['active', false]);
9151 * // The `_.property` iteratee shorthand.
9152 * _.every(users, 'active');
9155 function every(collection, predicate, guard) {
9156 var func = isArray(collection) ? arrayEvery : baseEvery;
9157 if (guard && isIterateeCall(collection, predicate, guard)) {
9158 predicate = undefined;
9160 return func(collection, getIteratee(predicate, 3));
9164 * Iterates over elements of `collection`, returning an array of all elements
9165 * `predicate` returns truthy for. The predicate is invoked with three
9166 * arguments: (value, index|key, collection).
9168 * **Note:** Unlike `_.remove`, this method returns a new array.
9173 * @category Collection
9174 * @param {Array|Object} collection The collection to iterate over.
9175 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9176 * @returns {Array} Returns the new filtered array.
9181 * { 'user': 'barney', 'age': 36, 'active': true },
9182 * { 'user': 'fred', 'age': 40, 'active': false }
9185 * _.filter(users, function(o) { return !o.active; });
9186 * // => objects for ['fred']
9188 * // The `_.matches` iteratee shorthand.
9189 * _.filter(users, { 'age': 36, 'active': true });
9190 * // => objects for ['barney']
9192 * // The `_.matchesProperty` iteratee shorthand.
9193 * _.filter(users, ['active', false]);
9194 * // => objects for ['fred']
9196 * // The `_.property` iteratee shorthand.
9197 * _.filter(users, 'active');
9198 * // => objects for ['barney']
9200 function filter(collection, predicate) {
9201 var func = isArray(collection) ? arrayFilter : baseFilter;
9202 return func(collection, getIteratee(predicate, 3));
9206 * Iterates over elements of `collection`, returning the first element
9207 * `predicate` returns truthy for. The predicate is invoked with three
9208 * arguments: (value, index|key, collection).
9213 * @category Collection
9214 * @param {Array|Object} collection The collection to inspect.
9215 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9216 * @param {number} [fromIndex=0] The index to search from.
9217 * @returns {*} Returns the matched element, else `undefined`.
9221 * { 'user': 'barney', 'age': 36, 'active': true },
9222 * { 'user': 'fred', 'age': 40, 'active': false },
9223 * { 'user': 'pebbles', 'age': 1, 'active': true }
9226 * _.find(users, function(o) { return o.age < 40; });
9227 * // => object for 'barney'
9229 * // The `_.matches` iteratee shorthand.
9230 * _.find(users, { 'age': 1, 'active': true });
9231 * // => object for 'pebbles'
9233 * // The `_.matchesProperty` iteratee shorthand.
9234 * _.find(users, ['active', false]);
9235 * // => object for 'fred'
9237 * // The `_.property` iteratee shorthand.
9238 * _.find(users, 'active');
9239 * // => object for 'barney'
9241 var find = createFind(findIndex);
9244 * This method is like `_.find` except that it iterates over elements of
9245 * `collection` from right to left.
9250 * @category Collection
9251 * @param {Array|Object} collection The collection to inspect.
9252 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9253 * @param {number} [fromIndex=collection.length-1] The index to search from.
9254 * @returns {*} Returns the matched element, else `undefined`.
9257 * _.findLast([1, 2, 3, 4], function(n) {
9258 * return n % 2 == 1;
9262 var findLast = createFind(findLastIndex);
9265 * Creates a flattened array of values by running each element in `collection`
9266 * thru `iteratee` and flattening the mapped results. The iteratee is invoked
9267 * with three arguments: (value, index|key, collection).
9272 * @category Collection
9273 * @param {Array|Object} collection The collection to iterate over.
9274 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9275 * @returns {Array} Returns the new flattened array.
9278 * function duplicate(n) {
9282 * _.flatMap([1, 2], duplicate);
9283 * // => [1, 1, 2, 2]
9285 function flatMap(collection, iteratee) {
9286 return baseFlatten(map(collection, iteratee), 1);
9290 * This method is like `_.flatMap` except that it recursively flattens the
9296 * @category Collection
9297 * @param {Array|Object} collection The collection to iterate over.
9298 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9299 * @returns {Array} Returns the new flattened array.
9302 * function duplicate(n) {
9303 * return [[[n, n]]];
9306 * _.flatMapDeep([1, 2], duplicate);
9307 * // => [1, 1, 2, 2]
9309 function flatMapDeep(collection, iteratee) {
9310 return baseFlatten(map(collection, iteratee), INFINITY);
9314 * This method is like `_.flatMap` except that it recursively flattens the
9315 * mapped results up to `depth` times.
9320 * @category Collection
9321 * @param {Array|Object} collection The collection to iterate over.
9322 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9323 * @param {number} [depth=1] The maximum recursion depth.
9324 * @returns {Array} Returns the new flattened array.
9327 * function duplicate(n) {
9328 * return [[[n, n]]];
9331 * _.flatMapDepth([1, 2], duplicate, 2);
9332 * // => [[1, 1], [2, 2]]
9334 function flatMapDepth(collection, iteratee, depth) {
9335 depth = depth === undefined ? 1 : toInteger(depth);
9336 return baseFlatten(map(collection, iteratee), depth);
9340 * Iterates over elements of `collection` and invokes `iteratee` for each element.
9341 * The iteratee is invoked with three arguments: (value, index|key, collection).
9342 * Iteratee functions may exit iteration early by explicitly returning `false`.
9344 * **Note:** As with other "Collections" methods, objects with a "length"
9345 * property are iterated like arrays. To avoid this behavior use `_.forIn`
9346 * or `_.forOwn` for object iteration.
9352 * @category Collection
9353 * @param {Array|Object} collection The collection to iterate over.
9354 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9355 * @returns {Array|Object} Returns `collection`.
9356 * @see _.forEachRight
9359 * _.forEach([1, 2], function(value) {
9360 * console.log(value);
9362 * // => Logs `1` then `2`.
9364 * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
9367 * // => Logs 'a' then 'b' (iteration order is not guaranteed).
9369 function forEach(collection, iteratee) {
9370 var func = isArray(collection) ? arrayEach : baseEach;
9371 return func(collection, getIteratee(iteratee, 3));
9375 * This method is like `_.forEach` except that it iterates over elements of
9376 * `collection` from right to left.
9382 * @category Collection
9383 * @param {Array|Object} collection The collection to iterate over.
9384 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9385 * @returns {Array|Object} Returns `collection`.
9389 * _.forEachRight([1, 2], function(value) {
9390 * console.log(value);
9392 * // => Logs `2` then `1`.
9394 function forEachRight(collection, iteratee) {
9395 var func = isArray(collection) ? arrayEachRight : baseEachRight;
9396 return func(collection, getIteratee(iteratee, 3));
9400 * Creates an object composed of keys generated from the results of running
9401 * each element of `collection` thru `iteratee`. The order of grouped values
9402 * is determined by the order they occur in `collection`. The corresponding
9403 * value of each key is an array of elements responsible for generating the
9404 * key. The iteratee is invoked with one argument: (value).
9409 * @category Collection
9410 * @param {Array|Object} collection The collection to iterate over.
9411 * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
9412 * @returns {Object} Returns the composed aggregate object.
9415 * _.groupBy([6.1, 4.2, 6.3], Math.floor);
9416 * // => { '4': [4.2], '6': [6.1, 6.3] }
9418 * // The `_.property` iteratee shorthand.
9419 * _.groupBy(['one', 'two', 'three'], 'length');
9420 * // => { '3': ['one', 'two'], '5': ['three'] }
9422 var groupBy = createAggregator(function(result, value, key) {
9423 if (hasOwnProperty.call(result, key)) {
9424 result[key].push(value);
9426 baseAssignValue(result, key, [value]);
9431 * Checks if `value` is in `collection`. If `collection` is a string, it's
9432 * checked for a substring of `value`, otherwise
9433 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
9434 * is used for equality comparisons. If `fromIndex` is negative, it's used as
9435 * the offset from the end of `collection`.
9440 * @category Collection
9441 * @param {Array|Object|string} collection The collection to inspect.
9442 * @param {*} value The value to search for.
9443 * @param {number} [fromIndex=0] The index to search from.
9444 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
9445 * @returns {boolean} Returns `true` if `value` is found, else `false`.
9448 * _.includes([1, 2, 3], 1);
9451 * _.includes([1, 2, 3], 1, 2);
9454 * _.includes({ 'a': 1, 'b': 2 }, 1);
9457 * _.includes('abcd', 'bc');
9460 function includes(collection, value, fromIndex, guard) {
9461 collection = isArrayLike(collection) ? collection : values(collection);
9462 fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
9464 var length = collection.length;
9465 if (fromIndex < 0) {
9466 fromIndex = nativeMax(length + fromIndex, 0);
9468 return isString(collection)
9469 ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
9470 : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
9474 * Invokes the method at `path` of each element in `collection`, returning
9475 * an array of the results of each invoked method. Any additional arguments
9476 * are provided to each invoked method. If `path` is a function, it's invoked
9477 * for, and `this` bound to, each element in `collection`.
9482 * @category Collection
9483 * @param {Array|Object} collection The collection to iterate over.
9484 * @param {Array|Function|string} path The path of the method to invoke or
9485 * the function invoked per iteration.
9486 * @param {...*} [args] The arguments to invoke each method with.
9487 * @returns {Array} Returns the array of results.
9490 * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
9491 * // => [[1, 5, 7], [1, 2, 3]]
9493 * _.invokeMap([123, 456], String.prototype.split, '');
9494 * // => [['1', '2', '3'], ['4', '5', '6']]
9496 var invokeMap = baseRest(function(collection, path, args) {
9498 isFunc = typeof path == 'function',
9499 result = isArrayLike(collection) ? Array(collection.length) : [];
9501 baseEach(collection, function(value) {
9502 result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
9508 * Creates an object composed of keys generated from the results of running
9509 * each element of `collection` thru `iteratee`. The corresponding value of
9510 * each key is the last element responsible for generating the key. The
9511 * iteratee is invoked with one argument: (value).
9516 * @category Collection
9517 * @param {Array|Object} collection The collection to iterate over.
9518 * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
9519 * @returns {Object} Returns the composed aggregate object.
9523 * { 'dir': 'left', 'code': 97 },
9524 * { 'dir': 'right', 'code': 100 }
9527 * _.keyBy(array, function(o) {
9528 * return String.fromCharCode(o.code);
9530 * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
9532 * _.keyBy(array, 'dir');
9533 * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
9535 var keyBy = createAggregator(function(result, value, key) {
9536 baseAssignValue(result, key, value);
9540 * Creates an array of values by running each element in `collection` thru
9541 * `iteratee`. The iteratee is invoked with three arguments:
9542 * (value, index|key, collection).
9544 * Many lodash methods are guarded to work as iteratees for methods like
9545 * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
9547 * The guarded methods are:
9548 * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
9549 * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
9550 * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
9551 * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
9556 * @category Collection
9557 * @param {Array|Object} collection The collection to iterate over.
9558 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9559 * @returns {Array} Returns the new mapped array.
9562 * function square(n) {
9566 * _.map([4, 8], square);
9569 * _.map({ 'a': 4, 'b': 8 }, square);
9570 * // => [16, 64] (iteration order is not guaranteed)
9573 * { 'user': 'barney' },
9574 * { 'user': 'fred' }
9577 * // The `_.property` iteratee shorthand.
9578 * _.map(users, 'user');
9579 * // => ['barney', 'fred']
9581 function map(collection, iteratee) {
9582 var func = isArray(collection) ? arrayMap : baseMap;
9583 return func(collection, getIteratee(iteratee, 3));
9587 * This method is like `_.sortBy` except that it allows specifying the sort
9588 * orders of the iteratees to sort by. If `orders` is unspecified, all values
9589 * are sorted in ascending order. Otherwise, specify an order of "desc" for
9590 * descending or "asc" for ascending sort order of corresponding values.
9595 * @category Collection
9596 * @param {Array|Object} collection The collection to iterate over.
9597 * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
9598 * The iteratees to sort by.
9599 * @param {string[]} [orders] The sort orders of `iteratees`.
9600 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
9601 * @returns {Array} Returns the new sorted array.
9605 * { 'user': 'fred', 'age': 48 },
9606 * { 'user': 'barney', 'age': 34 },
9607 * { 'user': 'fred', 'age': 40 },
9608 * { 'user': 'barney', 'age': 36 }
9611 * // Sort by `user` in ascending order and by `age` in descending order.
9612 * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
9613 * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
9615 function orderBy(collection, iteratees, orders, guard) {
9616 if (collection == null) {
9619 if (!isArray(iteratees)) {
9620 iteratees = iteratees == null ? [] : [iteratees];
9622 orders = guard ? undefined : orders;
9623 if (!isArray(orders)) {
9624 orders = orders == null ? [] : [orders];
9626 return baseOrderBy(collection, iteratees, orders);
9630 * Creates an array of elements split into two groups, the first of which
9631 * contains elements `predicate` returns truthy for, the second of which
9632 * contains elements `predicate` returns falsey for. The predicate is
9633 * invoked with one argument: (value).
9638 * @category Collection
9639 * @param {Array|Object} collection The collection to iterate over.
9640 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9641 * @returns {Array} Returns the array of grouped elements.
9645 * { 'user': 'barney', 'age': 36, 'active': false },
9646 * { 'user': 'fred', 'age': 40, 'active': true },
9647 * { 'user': 'pebbles', 'age': 1, 'active': false }
9650 * _.partition(users, function(o) { return o.active; });
9651 * // => objects for [['fred'], ['barney', 'pebbles']]
9653 * // The `_.matches` iteratee shorthand.
9654 * _.partition(users, { 'age': 1, 'active': false });
9655 * // => objects for [['pebbles'], ['barney', 'fred']]
9657 * // The `_.matchesProperty` iteratee shorthand.
9658 * _.partition(users, ['active', false]);
9659 * // => objects for [['barney', 'pebbles'], ['fred']]
9661 * // The `_.property` iteratee shorthand.
9662 * _.partition(users, 'active');
9663 * // => objects for [['fred'], ['barney', 'pebbles']]
9665 var partition = createAggregator(function(result, value, key) {
9666 result[key ? 0 : 1].push(value);
9667 }, function() { return [[], []]; });
9670 * Reduces `collection` to a value which is the accumulated result of running
9671 * each element in `collection` thru `iteratee`, where each successive
9672 * invocation is supplied the return value of the previous. If `accumulator`
9673 * is not given, the first element of `collection` is used as the initial
9674 * value. The iteratee is invoked with four arguments:
9675 * (accumulator, value, index|key, collection).
9677 * Many lodash methods are guarded to work as iteratees for methods like
9678 * `_.reduce`, `_.reduceRight`, and `_.transform`.
9680 * The guarded methods are:
9681 * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
9687 * @category Collection
9688 * @param {Array|Object} collection The collection to iterate over.
9689 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9690 * @param {*} [accumulator] The initial value.
9691 * @returns {*} Returns the accumulated value.
9692 * @see _.reduceRight
9695 * _.reduce([1, 2], function(sum, n) {
9700 * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
9701 * (result[value] || (result[value] = [])).push(key);
9704 * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
9706 function reduce(collection, iteratee, accumulator) {
9707 var func = isArray(collection) ? arrayReduce : baseReduce,
9708 initAccum = arguments.length < 3;
9710 return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
9714 * This method is like `_.reduce` except that it iterates over elements of
9715 * `collection` from right to left.
9720 * @category Collection
9721 * @param {Array|Object} collection The collection to iterate over.
9722 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9723 * @param {*} [accumulator] The initial value.
9724 * @returns {*} Returns the accumulated value.
9728 * var array = [[0, 1], [2, 3], [4, 5]];
9730 * _.reduceRight(array, function(flattened, other) {
9731 * return flattened.concat(other);
9733 * // => [4, 5, 2, 3, 0, 1]
9735 function reduceRight(collection, iteratee, accumulator) {
9736 var func = isArray(collection) ? arrayReduceRight : baseReduce,
9737 initAccum = arguments.length < 3;
9739 return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
9743 * The opposite of `_.filter`; this method returns the elements of `collection`
9744 * that `predicate` does **not** return truthy for.
9749 * @category Collection
9750 * @param {Array|Object} collection The collection to iterate over.
9751 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9752 * @returns {Array} Returns the new filtered array.
9757 * { 'user': 'barney', 'age': 36, 'active': false },
9758 * { 'user': 'fred', 'age': 40, 'active': true }
9761 * _.reject(users, function(o) { return !o.active; });
9762 * // => objects for ['fred']
9764 * // The `_.matches` iteratee shorthand.
9765 * _.reject(users, { 'age': 40, 'active': true });
9766 * // => objects for ['barney']
9768 * // The `_.matchesProperty` iteratee shorthand.
9769 * _.reject(users, ['active', false]);
9770 * // => objects for ['fred']
9772 * // The `_.property` iteratee shorthand.
9773 * _.reject(users, 'active');
9774 * // => objects for ['barney']
9776 function reject(collection, predicate) {
9777 var func = isArray(collection) ? arrayFilter : baseFilter;
9778 return func(collection, negate(getIteratee(predicate, 3)));
9782 * Gets a random element from `collection`.
9787 * @category Collection
9788 * @param {Array|Object} collection The collection to sample.
9789 * @returns {*} Returns the random element.
9792 * _.sample([1, 2, 3, 4]);
9795 function sample(collection) {
9796 var func = isArray(collection) ? arraySample : baseSample;
9797 return func(collection);
9801 * Gets `n` random elements at unique keys from `collection` up to the
9802 * size of `collection`.
9807 * @category Collection
9808 * @param {Array|Object} collection The collection to sample.
9809 * @param {number} [n=1] The number of elements to sample.
9810 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9811 * @returns {Array} Returns the random elements.
9814 * _.sampleSize([1, 2, 3], 2);
9817 * _.sampleSize([1, 2, 3], 4);
9820 function sampleSize(collection, n, guard) {
9821 if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
9826 var func = isArray(collection) ? arraySampleSize : baseSampleSize;
9827 return func(collection, n);
9831 * Creates an array of shuffled values, using a version of the
9832 * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
9837 * @category Collection
9838 * @param {Array|Object} collection The collection to shuffle.
9839 * @returns {Array} Returns the new shuffled array.
9842 * _.shuffle([1, 2, 3, 4]);
9843 * // => [4, 1, 3, 2]
9845 function shuffle(collection) {
9846 var func = isArray(collection) ? arrayShuffle : baseShuffle;
9847 return func(collection);
9851 * Gets the size of `collection` by returning its length for array-like
9852 * values or the number of own enumerable string keyed properties for objects.
9857 * @category Collection
9858 * @param {Array|Object|string} collection The collection to inspect.
9859 * @returns {number} Returns the collection size.
9862 * _.size([1, 2, 3]);
9865 * _.size({ 'a': 1, 'b': 2 });
9868 * _.size('pebbles');
9871 function size(collection) {
9872 if (collection == null) {
9875 if (isArrayLike(collection)) {
9876 return isString(collection) ? stringSize(collection) : collection.length;
9878 var tag = getTag(collection);
9879 if (tag == mapTag || tag == setTag) {
9880 return collection.size;
9882 return baseKeys(collection).length;
9886 * Checks if `predicate` returns truthy for **any** element of `collection`.
9887 * Iteration is stopped once `predicate` returns truthy. The predicate is
9888 * invoked with three arguments: (value, index|key, collection).
9893 * @category Collection
9894 * @param {Array|Object} collection The collection to iterate over.
9895 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9896 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9897 * @returns {boolean} Returns `true` if any element passes the predicate check,
9901 * _.some([null, 0, 'yes', false], Boolean);
9905 * { 'user': 'barney', 'active': true },
9906 * { 'user': 'fred', 'active': false }
9909 * // The `_.matches` iteratee shorthand.
9910 * _.some(users, { 'user': 'barney', 'active': false });
9913 * // The `_.matchesProperty` iteratee shorthand.
9914 * _.some(users, ['active', false]);
9917 * // The `_.property` iteratee shorthand.
9918 * _.some(users, 'active');
9921 function some(collection, predicate, guard) {
9922 var func = isArray(collection) ? arraySome : baseSome;
9923 if (guard && isIterateeCall(collection, predicate, guard)) {
9924 predicate = undefined;
9926 return func(collection, getIteratee(predicate, 3));
9930 * Creates an array of elements, sorted in ascending order by the results of
9931 * running each element in a collection thru each iteratee. This method
9932 * performs a stable sort, that is, it preserves the original sort order of
9933 * equal elements. The iteratees are invoked with one argument: (value).
9938 * @category Collection
9939 * @param {Array|Object} collection The collection to iterate over.
9940 * @param {...(Function|Function[])} [iteratees=[_.identity]]
9941 * The iteratees to sort by.
9942 * @returns {Array} Returns the new sorted array.
9946 * { 'user': 'fred', 'age': 48 },
9947 * { 'user': 'barney', 'age': 36 },
9948 * { 'user': 'fred', 'age': 40 },
9949 * { 'user': 'barney', 'age': 34 }
9952 * _.sortBy(users, [function(o) { return o.user; }]);
9953 * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
9955 * _.sortBy(users, ['user', 'age']);
9956 * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]
9958 var sortBy = baseRest(function(collection, iteratees) {
9959 if (collection == null) {
9962 var length = iteratees.length;
9963 if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
9965 } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
9966 iteratees = [iteratees[0]];
9968 return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
9971 /*------------------------------------------------------------------------*/
9974 * Gets the timestamp of the number of milliseconds that have elapsed since
9975 * the Unix epoch (1 January 1970 00:00:00 UTC).
9981 * @returns {number} Returns the timestamp.
9984 * _.defer(function(stamp) {
9985 * console.log(_.now() - stamp);
9987 * // => Logs the number of milliseconds it took for the deferred invocation.
9989 var now = ctxNow || function() {
9990 return root.Date.now();
9993 /*------------------------------------------------------------------------*/
9996 * The opposite of `_.before`; this method creates a function that invokes
9997 * `func` once it's called `n` or more times.
10002 * @category Function
10003 * @param {number} n The number of calls before `func` is invoked.
10004 * @param {Function} func The function to restrict.
10005 * @returns {Function} Returns the new restricted function.
10008 * var saves = ['profile', 'settings'];
10010 * var done = _.after(saves.length, function() {
10011 * console.log('done saving!');
10014 * _.forEach(saves, function(type) {
10015 * asyncSave({ 'type': type, 'complete': done });
10017 * // => Logs 'done saving!' after the two async saves have completed.
10019 function after(n, func) {
10020 if (typeof func != 'function') {
10021 throw new TypeError(FUNC_ERROR_TEXT);
10024 return function() {
10026 return func.apply(this, arguments);
10032 * Creates a function that invokes `func`, with up to `n` arguments,
10033 * ignoring any additional arguments.
10038 * @category Function
10039 * @param {Function} func The function to cap arguments for.
10040 * @param {number} [n=func.length] The arity cap.
10041 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10042 * @returns {Function} Returns the new capped function.
10045 * _.map(['6', '8', '10'], _.ary(parseInt, 1));
10048 function ary(func, n, guard) {
10049 n = guard ? undefined : n;
10050 n = (func && n == null) ? func.length : n;
10051 return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);
10055 * Creates a function that invokes `func`, with the `this` binding and arguments
10056 * of the created function, while it's called less than `n` times. Subsequent
10057 * calls to the created function return the result of the last `func` invocation.
10062 * @category Function
10063 * @param {number} n The number of calls at which `func` is no longer invoked.
10064 * @param {Function} func The function to restrict.
10065 * @returns {Function} Returns the new restricted function.
10068 * jQuery(element).on('click', _.before(5, addContactToList));
10069 * // => Allows adding up to 4 contacts to the list.
10071 function before(n, func) {
10073 if (typeof func != 'function') {
10074 throw new TypeError(FUNC_ERROR_TEXT);
10077 return function() {
10079 result = func.apply(this, arguments);
10089 * Creates a function that invokes `func` with the `this` binding of `thisArg`
10090 * and `partials` prepended to the arguments it receives.
10092 * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
10093 * may be used as a placeholder for partially applied arguments.
10095 * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
10096 * property of bound functions.
10101 * @category Function
10102 * @param {Function} func The function to bind.
10103 * @param {*} thisArg The `this` binding of `func`.
10104 * @param {...*} [partials] The arguments to be partially applied.
10105 * @returns {Function} Returns the new bound function.
10108 * function greet(greeting, punctuation) {
10109 * return greeting + ' ' + this.user + punctuation;
10112 * var object = { 'user': 'fred' };
10114 * var bound = _.bind(greet, object, 'hi');
10118 * // Bound with placeholders.
10119 * var bound = _.bind(greet, object, _, '!');
10123 var bind = baseRest(function(func, thisArg, partials) {
10124 var bitmask = WRAP_BIND_FLAG;
10125 if (partials.length) {
10126 var holders = replaceHolders(partials, getHolder(bind));
10127 bitmask |= WRAP_PARTIAL_FLAG;
10129 return createWrap(func, bitmask, thisArg, partials, holders);
10133 * Creates a function that invokes the method at `object[key]` with `partials`
10134 * prepended to the arguments it receives.
10136 * This method differs from `_.bind` by allowing bound functions to reference
10137 * methods that may be redefined or don't yet exist. See
10138 * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
10139 * for more details.
10141 * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
10142 * builds, may be used as a placeholder for partially applied arguments.
10147 * @category Function
10148 * @param {Object} object The object to invoke the method on.
10149 * @param {string} key The key of the method.
10150 * @param {...*} [partials] The arguments to be partially applied.
10151 * @returns {Function} Returns the new bound function.
10156 * 'greet': function(greeting, punctuation) {
10157 * return greeting + ' ' + this.user + punctuation;
10161 * var bound = _.bindKey(object, 'greet', 'hi');
10165 * object.greet = function(greeting, punctuation) {
10166 * return greeting + 'ya ' + this.user + punctuation;
10170 * // => 'hiya fred!'
10172 * // Bound with placeholders.
10173 * var bound = _.bindKey(object, 'greet', _, '!');
10175 * // => 'hiya fred!'
10177 var bindKey = baseRest(function(object, key, partials) {
10178 var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
10179 if (partials.length) {
10180 var holders = replaceHolders(partials, getHolder(bindKey));
10181 bitmask |= WRAP_PARTIAL_FLAG;
10183 return createWrap(key, bitmask, object, partials, holders);
10187 * Creates a function that accepts arguments of `func` and either invokes
10188 * `func` returning its result, if at least `arity` number of arguments have
10189 * been provided, or returns a function that accepts the remaining `func`
10190 * arguments, and so on. The arity of `func` may be specified if `func.length`
10191 * is not sufficient.
10193 * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
10194 * may be used as a placeholder for provided arguments.
10196 * **Note:** This method doesn't set the "length" property of curried functions.
10201 * @category Function
10202 * @param {Function} func The function to curry.
10203 * @param {number} [arity=func.length] The arity of `func`.
10204 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10205 * @returns {Function} Returns the new curried function.
10208 * var abc = function(a, b, c) {
10209 * return [a, b, c];
10212 * var curried = _.curry(abc);
10214 * curried(1)(2)(3);
10217 * curried(1, 2)(3);
10220 * curried(1, 2, 3);
10223 * // Curried with placeholders.
10224 * curried(1)(_, 3)(2);
10227 function curry(func, arity, guard) {
10228 arity = guard ? undefined : arity;
10229 var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
10230 result.placeholder = curry.placeholder;
10235 * This method is like `_.curry` except that arguments are applied to `func`
10236 * in the manner of `_.partialRight` instead of `_.partial`.
10238 * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
10239 * builds, may be used as a placeholder for provided arguments.
10241 * **Note:** This method doesn't set the "length" property of curried functions.
10246 * @category Function
10247 * @param {Function} func The function to curry.
10248 * @param {number} [arity=func.length] The arity of `func`.
10249 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10250 * @returns {Function} Returns the new curried function.
10253 * var abc = function(a, b, c) {
10254 * return [a, b, c];
10257 * var curried = _.curryRight(abc);
10259 * curried(3)(2)(1);
10262 * curried(2, 3)(1);
10265 * curried(1, 2, 3);
10268 * // Curried with placeholders.
10269 * curried(3)(1, _)(2);
10272 function curryRight(func, arity, guard) {
10273 arity = guard ? undefined : arity;
10274 var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
10275 result.placeholder = curryRight.placeholder;
10280 * Creates a debounced function that delays invoking `func` until after `wait`
10281 * milliseconds have elapsed since the last time the debounced function was
10282 * invoked. The debounced function comes with a `cancel` method to cancel
10283 * delayed `func` invocations and a `flush` method to immediately invoke them.
10284 * Provide `options` to indicate whether `func` should be invoked on the
10285 * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
10286 * with the last arguments provided to the debounced function. Subsequent
10287 * calls to the debounced function return the result of the last `func`
10290 * **Note:** If `leading` and `trailing` options are `true`, `func` is
10291 * invoked on the trailing edge of the timeout only if the debounced function
10292 * is invoked more than once during the `wait` timeout.
10294 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
10295 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
10297 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
10298 * for details over the differences between `_.debounce` and `_.throttle`.
10303 * @category Function
10304 * @param {Function} func The function to debounce.
10305 * @param {number} [wait=0] The number of milliseconds to delay.
10306 * @param {Object} [options={}] The options object.
10307 * @param {boolean} [options.leading=false]
10308 * Specify invoking on the leading edge of the timeout.
10309 * @param {number} [options.maxWait]
10310 * The maximum time `func` is allowed to be delayed before it's invoked.
10311 * @param {boolean} [options.trailing=true]
10312 * Specify invoking on the trailing edge of the timeout.
10313 * @returns {Function} Returns the new debounced function.
10316 * // Avoid costly calculations while the window size is in flux.
10317 * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
10319 * // Invoke `sendMail` when clicked, debouncing subsequent calls.
10320 * jQuery(element).on('click', _.debounce(sendMail, 300, {
10322 * 'trailing': false
10325 * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
10326 * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
10327 * var source = new EventSource('/stream');
10328 * jQuery(source).on('message', debounced);
10330 * // Cancel the trailing debounced invocation.
10331 * jQuery(window).on('popstate', debounced.cancel);
10333 function debounce(func, wait, options) {
10340 lastInvokeTime = 0,
10345 if (typeof func != 'function') {
10346 throw new TypeError(FUNC_ERROR_TEXT);
10348 wait = toNumber(wait) || 0;
10349 if (isObject(options)) {
10350 leading = !!options.leading;
10351 maxing = 'maxWait' in options;
10352 maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
10353 trailing = 'trailing' in options ? !!options.trailing : trailing;
10356 function invokeFunc(time) {
10357 var args = lastArgs,
10358 thisArg = lastThis;
10360 lastArgs = lastThis = undefined;
10361 lastInvokeTime = time;
10362 result = func.apply(thisArg, args);
10366 function leadingEdge(time) {
10367 // Reset any `maxWait` timer.
10368 lastInvokeTime = time;
10369 // Start the timer for the trailing edge.
10370 timerId = setTimeout(timerExpired, wait);
10371 // Invoke the leading edge.
10372 return leading ? invokeFunc(time) : result;
10375 function remainingWait(time) {
10376 var timeSinceLastCall = time - lastCallTime,
10377 timeSinceLastInvoke = time - lastInvokeTime,
10378 result = wait - timeSinceLastCall;
10380 return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
10383 function shouldInvoke(time) {
10384 var timeSinceLastCall = time - lastCallTime,
10385 timeSinceLastInvoke = time - lastInvokeTime;
10387 // Either this is the first call, activity has stopped and we're at the
10388 // trailing edge, the system time has gone backwards and we're treating
10389 // it as the trailing edge, or we've hit the `maxWait` limit.
10390 return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
10391 (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
10394 function timerExpired() {
10396 if (shouldInvoke(time)) {
10397 return trailingEdge(time);
10399 // Restart the timer.
10400 timerId = setTimeout(timerExpired, remainingWait(time));
10403 function trailingEdge(time) {
10404 timerId = undefined;
10406 // Only invoke if we have `lastArgs` which means `func` has been
10407 // debounced at least once.
10408 if (trailing && lastArgs) {
10409 return invokeFunc(time);
10411 lastArgs = lastThis = undefined;
10415 function cancel() {
10416 if (timerId !== undefined) {
10417 clearTimeout(timerId);
10419 lastInvokeTime = 0;
10420 lastArgs = lastCallTime = lastThis = timerId = undefined;
10424 return timerId === undefined ? result : trailingEdge(now());
10427 function debounced() {
10429 isInvoking = shouldInvoke(time);
10431 lastArgs = arguments;
10433 lastCallTime = time;
10436 if (timerId === undefined) {
10437 return leadingEdge(lastCallTime);
10440 // Handle invocations in a tight loop.
10441 timerId = setTimeout(timerExpired, wait);
10442 return invokeFunc(lastCallTime);
10445 if (timerId === undefined) {
10446 timerId = setTimeout(timerExpired, wait);
10450 debounced.cancel = cancel;
10451 debounced.flush = flush;
10456 * Defers invoking the `func` until the current call stack has cleared. Any
10457 * additional arguments are provided to `func` when it's invoked.
10462 * @category Function
10463 * @param {Function} func The function to defer.
10464 * @param {...*} [args] The arguments to invoke `func` with.
10465 * @returns {number} Returns the timer id.
10468 * _.defer(function(text) {
10469 * console.log(text);
10471 * // => Logs 'deferred' after one millisecond.
10473 var defer = baseRest(function(func, args) {
10474 return baseDelay(func, 1, args);
10478 * Invokes `func` after `wait` milliseconds. Any additional arguments are
10479 * provided to `func` when it's invoked.
10484 * @category Function
10485 * @param {Function} func The function to delay.
10486 * @param {number} wait The number of milliseconds to delay invocation.
10487 * @param {...*} [args] The arguments to invoke `func` with.
10488 * @returns {number} Returns the timer id.
10491 * _.delay(function(text) {
10492 * console.log(text);
10493 * }, 1000, 'later');
10494 * // => Logs 'later' after one second.
10496 var delay = baseRest(function(func, wait, args) {
10497 return baseDelay(func, toNumber(wait) || 0, args);
10501 * Creates a function that invokes `func` with arguments reversed.
10506 * @category Function
10507 * @param {Function} func The function to flip arguments for.
10508 * @returns {Function} Returns the new flipped function.
10511 * var flipped = _.flip(function() {
10512 * return _.toArray(arguments);
10515 * flipped('a', 'b', 'c', 'd');
10516 * // => ['d', 'c', 'b', 'a']
10518 function flip(func) {
10519 return createWrap(func, WRAP_FLIP_FLAG);
10523 * Creates a function that memoizes the result of `func`. If `resolver` is
10524 * provided, it determines the cache key for storing the result based on the
10525 * arguments provided to the memoized function. By default, the first argument
10526 * provided to the memoized function is used as the map cache key. The `func`
10527 * is invoked with the `this` binding of the memoized function.
10529 * **Note:** The cache is exposed as the `cache` property on the memoized
10530 * function. Its creation may be customized by replacing the `_.memoize.Cache`
10531 * constructor with one whose instances implement the
10532 * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
10533 * method interface of `clear`, `delete`, `get`, `has`, and `set`.
10538 * @category Function
10539 * @param {Function} func The function to have its output memoized.
10540 * @param {Function} [resolver] The function to resolve the cache key.
10541 * @returns {Function} Returns the new memoized function.
10544 * var object = { 'a': 1, 'b': 2 };
10545 * var other = { 'c': 3, 'd': 4 };
10547 * var values = _.memoize(_.values);
10558 * // Modify the result cache.
10559 * values.cache.set(object, ['a', 'b']);
10563 * // Replace `_.memoize.Cache`.
10564 * _.memoize.Cache = WeakMap;
10566 function memoize(func, resolver) {
10567 if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
10568 throw new TypeError(FUNC_ERROR_TEXT);
10570 var memoized = function() {
10571 var args = arguments,
10572 key = resolver ? resolver.apply(this, args) : args[0],
10573 cache = memoized.cache;
10575 if (cache.has(key)) {
10576 return cache.get(key);
10578 var result = func.apply(this, args);
10579 memoized.cache = cache.set(key, result) || cache;
10582 memoized.cache = new (memoize.Cache || MapCache);
10586 // Expose `MapCache`.
10587 memoize.Cache = MapCache;
10590 * Creates a function that negates the result of the predicate `func`. The
10591 * `func` predicate is invoked with the `this` binding and arguments of the
10592 * created function.
10597 * @category Function
10598 * @param {Function} predicate The predicate to negate.
10599 * @returns {Function} Returns the new negated function.
10602 * function isEven(n) {
10603 * return n % 2 == 0;
10606 * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
10609 function negate(predicate) {
10610 if (typeof predicate != 'function') {
10611 throw new TypeError(FUNC_ERROR_TEXT);
10613 return function() {
10614 var args = arguments;
10615 switch (args.length) {
10616 case 0: return !predicate.call(this);
10617 case 1: return !predicate.call(this, args[0]);
10618 case 2: return !predicate.call(this, args[0], args[1]);
10619 case 3: return !predicate.call(this, args[0], args[1], args[2]);
10621 return !predicate.apply(this, args);
10626 * Creates a function that is restricted to invoking `func` once. Repeat calls
10627 * to the function return the value of the first invocation. The `func` is
10628 * invoked with the `this` binding and arguments of the created function.
10633 * @category Function
10634 * @param {Function} func The function to restrict.
10635 * @returns {Function} Returns the new restricted function.
10638 * var initialize = _.once(createApplication);
10641 * // => `createApplication` is invoked once
10643 function once(func) {
10644 return before(2, func);
10648 * Creates a function that invokes `func` with its arguments transformed.
10653 * @category Function
10654 * @param {Function} func The function to wrap.
10655 * @param {...(Function|Function[])} [transforms=[_.identity]]
10656 * The argument transforms.
10657 * @returns {Function} Returns the new function.
10660 * function doubled(n) {
10664 * function square(n) {
10668 * var func = _.overArgs(function(x, y) {
10670 * }, [square, doubled]);
10678 var overArgs = castRest(function(func, transforms) {
10679 transforms = (transforms.length == 1 && isArray(transforms[0]))
10680 ? arrayMap(transforms[0], baseUnary(getIteratee()))
10681 : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
10683 var funcsLength = transforms.length;
10684 return baseRest(function(args) {
10686 length = nativeMin(args.length, funcsLength);
10688 while (++index < length) {
10689 args[index] = transforms[index].call(this, args[index]);
10691 return apply(func, this, args);
10696 * Creates a function that invokes `func` with `partials` prepended to the
10697 * arguments it receives. This method is like `_.bind` except it does **not**
10698 * alter the `this` binding.
10700 * The `_.partial.placeholder` value, which defaults to `_` in monolithic
10701 * builds, may be used as a placeholder for partially applied arguments.
10703 * **Note:** This method doesn't set the "length" property of partially
10704 * applied functions.
10709 * @category Function
10710 * @param {Function} func The function to partially apply arguments to.
10711 * @param {...*} [partials] The arguments to be partially applied.
10712 * @returns {Function} Returns the new partially applied function.
10715 * function greet(greeting, name) {
10716 * return greeting + ' ' + name;
10719 * var sayHelloTo = _.partial(greet, 'hello');
10720 * sayHelloTo('fred');
10721 * // => 'hello fred'
10723 * // Partially applied with placeholders.
10724 * var greetFred = _.partial(greet, _, 'fred');
10728 var partial = baseRest(function(func, partials) {
10729 var holders = replaceHolders(partials, getHolder(partial));
10730 return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);
10734 * This method is like `_.partial` except that partially applied arguments
10735 * are appended to the arguments it receives.
10737 * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
10738 * builds, may be used as a placeholder for partially applied arguments.
10740 * **Note:** This method doesn't set the "length" property of partially
10741 * applied functions.
10746 * @category Function
10747 * @param {Function} func The function to partially apply arguments to.
10748 * @param {...*} [partials] The arguments to be partially applied.
10749 * @returns {Function} Returns the new partially applied function.
10752 * function greet(greeting, name) {
10753 * return greeting + ' ' + name;
10756 * var greetFred = _.partialRight(greet, 'fred');
10760 * // Partially applied with placeholders.
10761 * var sayHelloTo = _.partialRight(greet, 'hello', _);
10762 * sayHelloTo('fred');
10763 * // => 'hello fred'
10765 var partialRight = baseRest(function(func, partials) {
10766 var holders = replaceHolders(partials, getHolder(partialRight));
10767 return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);
10771 * Creates a function that invokes `func` with arguments arranged according
10772 * to the specified `indexes` where the argument value at the first index is
10773 * provided as the first argument, the argument value at the second index is
10774 * provided as the second argument, and so on.
10779 * @category Function
10780 * @param {Function} func The function to rearrange arguments for.
10781 * @param {...(number|number[])} indexes The arranged argument indexes.
10782 * @returns {Function} Returns the new function.
10785 * var rearged = _.rearg(function(a, b, c) {
10786 * return [a, b, c];
10789 * rearged('b', 'c', 'a')
10790 * // => ['a', 'b', 'c']
10792 var rearg = flatRest(function(func, indexes) {
10793 return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);
10797 * Creates a function that invokes `func` with the `this` binding of the
10798 * created function and arguments from `start` and beyond provided as
10801 * **Note:** This method is based on the
10802 * [rest parameter](https://mdn.io/rest_parameters).
10807 * @category Function
10808 * @param {Function} func The function to apply a rest parameter to.
10809 * @param {number} [start=func.length-1] The start position of the rest parameter.
10810 * @returns {Function} Returns the new function.
10813 * var say = _.rest(function(what, names) {
10814 * return what + ' ' + _.initial(names).join(', ') +
10815 * (_.size(names) > 1 ? ', & ' : '') + _.last(names);
10818 * say('hello', 'fred', 'barney', 'pebbles');
10819 * // => 'hello fred, barney, & pebbles'
10821 function rest(func, start) {
10822 if (typeof func != 'function') {
10823 throw new TypeError(FUNC_ERROR_TEXT);
10825 start = start === undefined ? start : toInteger(start);
10826 return baseRest(func, start);
10830 * Creates a function that invokes `func` with the `this` binding of the
10831 * create function and an array of arguments much like
10832 * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
10834 * **Note:** This method is based on the
10835 * [spread operator](https://mdn.io/spread_operator).
10840 * @category Function
10841 * @param {Function} func The function to spread arguments over.
10842 * @param {number} [start=0] The start position of the spread.
10843 * @returns {Function} Returns the new function.
10846 * var say = _.spread(function(who, what) {
10847 * return who + ' says ' + what;
10850 * say(['fred', 'hello']);
10851 * // => 'fred says hello'
10853 * var numbers = Promise.all([
10854 * Promise.resolve(40),
10855 * Promise.resolve(36)
10858 * numbers.then(_.spread(function(x, y) {
10861 * // => a Promise of 76
10863 function spread(func, start) {
10864 if (typeof func != 'function') {
10865 throw new TypeError(FUNC_ERROR_TEXT);
10867 start = start === undefined ? 0 : nativeMax(toInteger(start), 0);
10868 return baseRest(function(args) {
10869 var array = args[start],
10870 lastIndex = args.length - 1,
10871 otherArgs = castSlice(args, 0, start);
10874 arrayPush(otherArgs, array);
10876 if (start != lastIndex) {
10877 arrayPush(otherArgs, castSlice(args, start + 1));
10879 return apply(func, this, otherArgs);
10884 * Creates a throttled function that only invokes `func` at most once per
10885 * every `wait` milliseconds. The throttled function comes with a `cancel`
10886 * method to cancel delayed `func` invocations and a `flush` method to
10887 * immediately invoke them. Provide `options` to indicate whether `func`
10888 * should be invoked on the leading and/or trailing edge of the `wait`
10889 * timeout. The `func` is invoked with the last arguments provided to the
10890 * throttled function. Subsequent calls to the throttled function return the
10891 * result of the last `func` invocation.
10893 * **Note:** If `leading` and `trailing` options are `true`, `func` is
10894 * invoked on the trailing edge of the timeout only if the throttled function
10895 * is invoked more than once during the `wait` timeout.
10897 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
10898 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
10900 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
10901 * for details over the differences between `_.throttle` and `_.debounce`.
10906 * @category Function
10907 * @param {Function} func The function to throttle.
10908 * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
10909 * @param {Object} [options={}] The options object.
10910 * @param {boolean} [options.leading=true]
10911 * Specify invoking on the leading edge of the timeout.
10912 * @param {boolean} [options.trailing=true]
10913 * Specify invoking on the trailing edge of the timeout.
10914 * @returns {Function} Returns the new throttled function.
10917 * // Avoid excessively updating the position while scrolling.
10918 * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
10920 * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
10921 * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
10922 * jQuery(element).on('click', throttled);
10924 * // Cancel the trailing throttled invocation.
10925 * jQuery(window).on('popstate', throttled.cancel);
10927 function throttle(func, wait, options) {
10928 var leading = true,
10931 if (typeof func != 'function') {
10932 throw new TypeError(FUNC_ERROR_TEXT);
10934 if (isObject(options)) {
10935 leading = 'leading' in options ? !!options.leading : leading;
10936 trailing = 'trailing' in options ? !!options.trailing : trailing;
10938 return debounce(func, wait, {
10939 'leading': leading,
10941 'trailing': trailing
10946 * Creates a function that accepts up to one argument, ignoring any
10947 * additional arguments.
10952 * @category Function
10953 * @param {Function} func The function to cap arguments for.
10954 * @returns {Function} Returns the new capped function.
10957 * _.map(['6', '8', '10'], _.unary(parseInt));
10960 function unary(func) {
10961 return ary(func, 1);
10965 * Creates a function that provides `value` to `wrapper` as its first
10966 * argument. Any additional arguments provided to the function are appended
10967 * to those provided to the `wrapper`. The wrapper is invoked with the `this`
10968 * binding of the created function.
10973 * @category Function
10974 * @param {*} value The value to wrap.
10975 * @param {Function} [wrapper=identity] The wrapper function.
10976 * @returns {Function} Returns the new function.
10979 * var p = _.wrap(_.escape, function(func, text) {
10980 * return '<p>' + func(text) + '</p>';
10983 * p('fred, barney, & pebbles');
10984 * // => '<p>fred, barney, & pebbles</p>'
10986 function wrap(value, wrapper) {
10987 return partial(castFunction(wrapper), value);
10990 /*------------------------------------------------------------------------*/
10993 * Casts `value` as an array if it's not one.
10999 * @param {*} value The value to inspect.
11000 * @returns {Array} Returns the cast array.
11006 * _.castArray({ 'a': 1 });
11007 * // => [{ 'a': 1 }]
11009 * _.castArray('abc');
11012 * _.castArray(null);
11015 * _.castArray(undefined);
11016 * // => [undefined]
11021 * var array = [1, 2, 3];
11022 * console.log(_.castArray(array) === array);
11025 function castArray() {
11026 if (!arguments.length) {
11029 var value = arguments[0];
11030 return isArray(value) ? value : [value];
11034 * Creates a shallow clone of `value`.
11036 * **Note:** This method is loosely based on the
11037 * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
11038 * and supports cloning arrays, array buffers, booleans, date objects, maps,
11039 * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
11040 * arrays. The own enumerable properties of `arguments` objects are cloned
11041 * as plain objects. An empty object is returned for uncloneable values such
11042 * as error objects, functions, DOM nodes, and WeakMaps.
11048 * @param {*} value The value to clone.
11049 * @returns {*} Returns the cloned value.
11053 * var objects = [{ 'a': 1 }, { 'b': 2 }];
11055 * var shallow = _.clone(objects);
11056 * console.log(shallow[0] === objects[0]);
11059 function clone(value) {
11060 return baseClone(value, CLONE_SYMBOLS_FLAG);
11064 * This method is like `_.clone` except that it accepts `customizer` which
11065 * is invoked to produce the cloned value. If `customizer` returns `undefined`,
11066 * cloning is handled by the method instead. The `customizer` is invoked with
11067 * up to four arguments; (value [, index|key, object, stack]).
11073 * @param {*} value The value to clone.
11074 * @param {Function} [customizer] The function to customize cloning.
11075 * @returns {*} Returns the cloned value.
11076 * @see _.cloneDeepWith
11079 * function customizer(value) {
11080 * if (_.isElement(value)) {
11081 * return value.cloneNode(false);
11085 * var el = _.cloneWith(document.body, customizer);
11087 * console.log(el === document.body);
11089 * console.log(el.nodeName);
11091 * console.log(el.childNodes.length);
11094 function cloneWith(value, customizer) {
11095 customizer = typeof customizer == 'function' ? customizer : undefined;
11096 return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);
11100 * This method is like `_.clone` except that it recursively clones `value`.
11106 * @param {*} value The value to recursively clone.
11107 * @returns {*} Returns the deep cloned value.
11111 * var objects = [{ 'a': 1 }, { 'b': 2 }];
11113 * var deep = _.cloneDeep(objects);
11114 * console.log(deep[0] === objects[0]);
11117 function cloneDeep(value) {
11118 return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
11122 * This method is like `_.cloneWith` except that it recursively clones `value`.
11128 * @param {*} value The value to recursively clone.
11129 * @param {Function} [customizer] The function to customize cloning.
11130 * @returns {*} Returns the deep cloned value.
11134 * function customizer(value) {
11135 * if (_.isElement(value)) {
11136 * return value.cloneNode(true);
11140 * var el = _.cloneDeepWith(document.body, customizer);
11142 * console.log(el === document.body);
11144 * console.log(el.nodeName);
11146 * console.log(el.childNodes.length);
11149 function cloneDeepWith(value, customizer) {
11150 customizer = typeof customizer == 'function' ? customizer : undefined;
11151 return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
11155 * Checks if `object` conforms to `source` by invoking the predicate
11156 * properties of `source` with the corresponding property values of `object`.
11158 * **Note:** This method is equivalent to `_.conforms` when `source` is
11159 * partially applied.
11165 * @param {Object} object The object to inspect.
11166 * @param {Object} source The object of property predicates to conform to.
11167 * @returns {boolean} Returns `true` if `object` conforms, else `false`.
11170 * var object = { 'a': 1, 'b': 2 };
11172 * _.conformsTo(object, { 'b': function(n) { return n > 1; } });
11175 * _.conformsTo(object, { 'b': function(n) { return n > 2; } });
11178 function conformsTo(object, source) {
11179 return source == null || baseConformsTo(object, source, keys(source));
11184 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
11185 * comparison between two values to determine if they are equivalent.
11191 * @param {*} value The value to compare.
11192 * @param {*} other The other value to compare.
11193 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
11196 * var object = { 'a': 1 };
11197 * var other = { 'a': 1 };
11199 * _.eq(object, object);
11202 * _.eq(object, other);
11208 * _.eq('a', Object('a'));
11214 function eq(value, other) {
11215 return value === other || (value !== value && other !== other);
11219 * Checks if `value` is greater than `other`.
11225 * @param {*} value The value to compare.
11226 * @param {*} other The other value to compare.
11227 * @returns {boolean} Returns `true` if `value` is greater than `other`,
11241 var gt = createRelationalOperation(baseGt);
11244 * Checks if `value` is greater than or equal to `other`.
11250 * @param {*} value The value to compare.
11251 * @param {*} other The other value to compare.
11252 * @returns {boolean} Returns `true` if `value` is greater than or equal to
11253 * `other`, else `false`.
11266 var gte = createRelationalOperation(function(value, other) {
11267 return value >= other;
11271 * Checks if `value` is likely an `arguments` object.
11277 * @param {*} value The value to check.
11278 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
11282 * _.isArguments(function() { return arguments; }());
11285 * _.isArguments([1, 2, 3]);
11288 var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
11289 return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
11290 !propertyIsEnumerable.call(value, 'callee');
11294 * Checks if `value` is classified as an `Array` object.
11300 * @param {*} value The value to check.
11301 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
11304 * _.isArray([1, 2, 3]);
11307 * _.isArray(document.body.children);
11310 * _.isArray('abc');
11313 * _.isArray(_.noop);
11316 var isArray = Array.isArray;
11319 * Checks if `value` is classified as an `ArrayBuffer` object.
11325 * @param {*} value The value to check.
11326 * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
11329 * _.isArrayBuffer(new ArrayBuffer(2));
11332 * _.isArrayBuffer(new Array(2));
11335 var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
11338 * Checks if `value` is array-like. A value is considered array-like if it's
11339 * not a function and has a `value.length` that's an integer greater than or
11340 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
11346 * @param {*} value The value to check.
11347 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
11350 * _.isArrayLike([1, 2, 3]);
11353 * _.isArrayLike(document.body.children);
11356 * _.isArrayLike('abc');
11359 * _.isArrayLike(_.noop);
11362 function isArrayLike(value) {
11363 return value != null && isLength(value.length) && !isFunction(value);
11367 * This method is like `_.isArrayLike` except that it also checks if `value`
11374 * @param {*} value The value to check.
11375 * @returns {boolean} Returns `true` if `value` is an array-like object,
11379 * _.isArrayLikeObject([1, 2, 3]);
11382 * _.isArrayLikeObject(document.body.children);
11385 * _.isArrayLikeObject('abc');
11388 * _.isArrayLikeObject(_.noop);
11391 function isArrayLikeObject(value) {
11392 return isObjectLike(value) && isArrayLike(value);
11396 * Checks if `value` is classified as a boolean primitive or object.
11402 * @param {*} value The value to check.
11403 * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
11406 * _.isBoolean(false);
11409 * _.isBoolean(null);
11412 function isBoolean(value) {
11413 return value === true || value === false ||
11414 (isObjectLike(value) && baseGetTag(value) == boolTag);
11418 * Checks if `value` is a buffer.
11424 * @param {*} value The value to check.
11425 * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
11428 * _.isBuffer(new Buffer(2));
11431 * _.isBuffer(new Uint8Array(2));
11434 var isBuffer = nativeIsBuffer || stubFalse;
11437 * Checks if `value` is classified as a `Date` object.
11443 * @param {*} value The value to check.
11444 * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
11447 * _.isDate(new Date);
11450 * _.isDate('Mon April 23 2012');
11453 var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
11456 * Checks if `value` is likely a DOM element.
11462 * @param {*} value The value to check.
11463 * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
11466 * _.isElement(document.body);
11469 * _.isElement('<body>');
11472 function isElement(value) {
11473 return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
11477 * Checks if `value` is an empty object, collection, map, or set.
11479 * Objects are considered empty if they have no own enumerable string keyed
11482 * Array-like values such as `arguments` objects, arrays, buffers, strings, or
11483 * jQuery-like collections are considered empty if they have a `length` of `0`.
11484 * Similarly, maps and sets are considered empty if they have a `size` of `0`.
11490 * @param {*} value The value to check.
11491 * @returns {boolean} Returns `true` if `value` is empty, else `false`.
11503 * _.isEmpty([1, 2, 3]);
11506 * _.isEmpty({ 'a': 1 });
11509 function isEmpty(value) {
11510 if (value == null) {
11513 if (isArrayLike(value) &&
11514 (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
11515 isBuffer(value) || isTypedArray(value) || isArguments(value))) {
11516 return !value.length;
11518 var tag = getTag(value);
11519 if (tag == mapTag || tag == setTag) {
11520 return !value.size;
11522 if (isPrototype(value)) {
11523 return !baseKeys(value).length;
11525 for (var key in value) {
11526 if (hasOwnProperty.call(value, key)) {
11534 * Performs a deep comparison between two values to determine if they are
11537 * **Note:** This method supports comparing arrays, array buffers, booleans,
11538 * date objects, error objects, maps, numbers, `Object` objects, regexes,
11539 * sets, strings, symbols, and typed arrays. `Object` objects are compared
11540 * by their own, not inherited, enumerable properties. Functions and DOM
11541 * nodes are **not** supported.
11547 * @param {*} value The value to compare.
11548 * @param {*} other The other value to compare.
11549 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
11552 * var object = { 'a': 1 };
11553 * var other = { 'a': 1 };
11555 * _.isEqual(object, other);
11558 * object === other;
11561 function isEqual(value, other) {
11562 return baseIsEqual(value, other);
11566 * This method is like `_.isEqual` except that it accepts `customizer` which
11567 * is invoked to compare values. If `customizer` returns `undefined`, comparisons
11568 * are handled by the method instead. The `customizer` is invoked with up to
11569 * six arguments: (objValue, othValue [, index|key, object, other, stack]).
11575 * @param {*} value The value to compare.
11576 * @param {*} other The other value to compare.
11577 * @param {Function} [customizer] The function to customize comparisons.
11578 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
11581 * function isGreeting(value) {
11582 * return /^h(?:i|ello)$/.test(value);
11585 * function customizer(objValue, othValue) {
11586 * if (isGreeting(objValue) && isGreeting(othValue)) {
11591 * var array = ['hello', 'goodbye'];
11592 * var other = ['hi', 'goodbye'];
11594 * _.isEqualWith(array, other, customizer);
11597 function isEqualWith(value, other, customizer) {
11598 customizer = typeof customizer == 'function' ? customizer : undefined;
11599 var result = customizer ? customizer(value, other) : undefined;
11600 return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;
11604 * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
11605 * `SyntaxError`, `TypeError`, or `URIError` object.
11611 * @param {*} value The value to check.
11612 * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
11615 * _.isError(new Error);
11618 * _.isError(Error);
11621 function isError(value) {
11622 if (!isObjectLike(value)) {
11625 var tag = baseGetTag(value);
11626 return tag == errorTag || tag == domExcTag ||
11627 (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));
11631 * Checks if `value` is a finite primitive number.
11633 * **Note:** This method is based on
11634 * [`Number.isFinite`](https://mdn.io/Number/isFinite).
11640 * @param {*} value The value to check.
11641 * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
11647 * _.isFinite(Number.MIN_VALUE);
11650 * _.isFinite(Infinity);
11656 function isFinite(value) {
11657 return typeof value == 'number' && nativeIsFinite(value);
11661 * Checks if `value` is classified as a `Function` object.
11667 * @param {*} value The value to check.
11668 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
11674 * _.isFunction(/abc/);
11677 function isFunction(value) {
11678 if (!isObject(value)) {
11681 // The use of `Object#toString` avoids issues with the `typeof` operator
11682 // in Safari 9 which returns 'object' for typed arrays and other constructors.
11683 var tag = baseGetTag(value);
11684 return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
11688 * Checks if `value` is an integer.
11690 * **Note:** This method is based on
11691 * [`Number.isInteger`](https://mdn.io/Number/isInteger).
11697 * @param {*} value The value to check.
11698 * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
11704 * _.isInteger(Number.MIN_VALUE);
11707 * _.isInteger(Infinity);
11710 * _.isInteger('3');
11713 function isInteger(value) {
11714 return typeof value == 'number' && value == toInteger(value);
11718 * Checks if `value` is a valid array-like length.
11720 * **Note:** This method is loosely based on
11721 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
11727 * @param {*} value The value to check.
11728 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
11734 * _.isLength(Number.MIN_VALUE);
11737 * _.isLength(Infinity);
11743 function isLength(value) {
11744 return typeof value == 'number' &&
11745 value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
11749 * Checks if `value` is the
11750 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
11751 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
11757 * @param {*} value The value to check.
11758 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
11764 * _.isObject([1, 2, 3]);
11767 * _.isObject(_.noop);
11770 * _.isObject(null);
11773 function isObject(value) {
11774 var type = typeof value;
11775 return value != null && (type == 'object' || type == 'function');
11779 * Checks if `value` is object-like. A value is object-like if it's not `null`
11780 * and has a `typeof` result of "object".
11786 * @param {*} value The value to check.
11787 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
11790 * _.isObjectLike({});
11793 * _.isObjectLike([1, 2, 3]);
11796 * _.isObjectLike(_.noop);
11799 * _.isObjectLike(null);
11802 function isObjectLike(value) {
11803 return value != null && typeof value == 'object';
11807 * Checks if `value` is classified as a `Map` object.
11813 * @param {*} value The value to check.
11814 * @returns {boolean} Returns `true` if `value` is a map, else `false`.
11817 * _.isMap(new Map);
11820 * _.isMap(new WeakMap);
11823 var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
11826 * Performs a partial deep comparison between `object` and `source` to
11827 * determine if `object` contains equivalent property values.
11829 * **Note:** This method is equivalent to `_.matches` when `source` is
11830 * partially applied.
11832 * Partial comparisons will match empty array and empty object `source`
11833 * values against any array or object value, respectively. See `_.isEqual`
11834 * for a list of supported value comparisons.
11840 * @param {Object} object The object to inspect.
11841 * @param {Object} source The object of property values to match.
11842 * @returns {boolean} Returns `true` if `object` is a match, else `false`.
11845 * var object = { 'a': 1, 'b': 2 };
11847 * _.isMatch(object, { 'b': 2 });
11850 * _.isMatch(object, { 'b': 1 });
11853 function isMatch(object, source) {
11854 return object === source || baseIsMatch(object, source, getMatchData(source));
11858 * This method is like `_.isMatch` except that it accepts `customizer` which
11859 * is invoked to compare values. If `customizer` returns `undefined`, comparisons
11860 * are handled by the method instead. The `customizer` is invoked with five
11861 * arguments: (objValue, srcValue, index|key, object, source).
11867 * @param {Object} object The object to inspect.
11868 * @param {Object} source The object of property values to match.
11869 * @param {Function} [customizer] The function to customize comparisons.
11870 * @returns {boolean} Returns `true` if `object` is a match, else `false`.
11873 * function isGreeting(value) {
11874 * return /^h(?:i|ello)$/.test(value);
11877 * function customizer(objValue, srcValue) {
11878 * if (isGreeting(objValue) && isGreeting(srcValue)) {
11883 * var object = { 'greeting': 'hello' };
11884 * var source = { 'greeting': 'hi' };
11886 * _.isMatchWith(object, source, customizer);
11889 function isMatchWith(object, source, customizer) {
11890 customizer = typeof customizer == 'function' ? customizer : undefined;
11891 return baseIsMatch(object, source, getMatchData(source), customizer);
11895 * Checks if `value` is `NaN`.
11897 * **Note:** This method is based on
11898 * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
11899 * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
11900 * `undefined` and other non-number values.
11906 * @param {*} value The value to check.
11907 * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
11913 * _.isNaN(new Number(NaN));
11916 * isNaN(undefined);
11919 * _.isNaN(undefined);
11922 function isNaN(value) {
11923 // An `NaN` primitive is the only value that is not equal to itself.
11924 // Perform the `toStringTag` check first to avoid errors with some
11925 // ActiveX objects in IE.
11926 return isNumber(value) && value != +value;
11930 * Checks if `value` is a pristine native function.
11932 * **Note:** This method can't reliably detect native functions in the presence
11933 * of the core-js package because core-js circumvents this kind of detection.
11934 * Despite multiple requests, the core-js maintainer has made it clear: any
11935 * attempt to fix the detection will be obstructed. As a result, we're left
11936 * with little choice but to throw an error. Unfortunately, this also affects
11937 * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
11938 * which rely on core-js.
11944 * @param {*} value The value to check.
11945 * @returns {boolean} Returns `true` if `value` is a native function,
11949 * _.isNative(Array.prototype.push);
11955 function isNative(value) {
11956 if (isMaskable(value)) {
11957 throw new Error(CORE_ERROR_TEXT);
11959 return baseIsNative(value);
11963 * Checks if `value` is `null`.
11969 * @param {*} value The value to check.
11970 * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
11976 * _.isNull(void 0);
11979 function isNull(value) {
11980 return value === null;
11984 * Checks if `value` is `null` or `undefined`.
11990 * @param {*} value The value to check.
11991 * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
12003 function isNil(value) {
12004 return value == null;
12008 * Checks if `value` is classified as a `Number` primitive or object.
12010 * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
12011 * classified as numbers, use the `_.isFinite` method.
12017 * @param {*} value The value to check.
12018 * @returns {boolean} Returns `true` if `value` is a number, else `false`.
12024 * _.isNumber(Number.MIN_VALUE);
12027 * _.isNumber(Infinity);
12033 function isNumber(value) {
12034 return typeof value == 'number' ||
12035 (isObjectLike(value) && baseGetTag(value) == numberTag);
12039 * Checks if `value` is a plain object, that is, an object created by the
12040 * `Object` constructor or one with a `[[Prototype]]` of `null`.
12046 * @param {*} value The value to check.
12047 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
12054 * _.isPlainObject(new Foo);
12057 * _.isPlainObject([1, 2, 3]);
12060 * _.isPlainObject({ 'x': 0, 'y': 0 });
12063 * _.isPlainObject(Object.create(null));
12066 function isPlainObject(value) {
12067 if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
12070 var proto = getPrototype(value);
12071 if (proto === null) {
12074 var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
12075 return typeof Ctor == 'function' && Ctor instanceof Ctor &&
12076 funcToString.call(Ctor) == objectCtorString;
12080 * Checks if `value` is classified as a `RegExp` object.
12086 * @param {*} value The value to check.
12087 * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
12090 * _.isRegExp(/abc/);
12093 * _.isRegExp('/abc/');
12096 var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
12099 * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
12100 * double precision number which isn't the result of a rounded unsafe integer.
12102 * **Note:** This method is based on
12103 * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
12109 * @param {*} value The value to check.
12110 * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
12113 * _.isSafeInteger(3);
12116 * _.isSafeInteger(Number.MIN_VALUE);
12119 * _.isSafeInteger(Infinity);
12122 * _.isSafeInteger('3');
12125 function isSafeInteger(value) {
12126 return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
12130 * Checks if `value` is classified as a `Set` object.
12136 * @param {*} value The value to check.
12137 * @returns {boolean} Returns `true` if `value` is a set, else `false`.
12140 * _.isSet(new Set);
12143 * _.isSet(new WeakSet);
12146 var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
12149 * Checks if `value` is classified as a `String` primitive or object.
12155 * @param {*} value The value to check.
12156 * @returns {boolean} Returns `true` if `value` is a string, else `false`.
12159 * _.isString('abc');
12165 function isString(value) {
12166 return typeof value == 'string' ||
12167 (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
12171 * Checks if `value` is classified as a `Symbol` primitive or object.
12177 * @param {*} value The value to check.
12178 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
12181 * _.isSymbol(Symbol.iterator);
12184 * _.isSymbol('abc');
12187 function isSymbol(value) {
12188 return typeof value == 'symbol' ||
12189 (isObjectLike(value) && baseGetTag(value) == symbolTag);
12193 * Checks if `value` is classified as a typed array.
12199 * @param {*} value The value to check.
12200 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
12203 * _.isTypedArray(new Uint8Array);
12206 * _.isTypedArray([]);
12209 var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
12212 * Checks if `value` is `undefined`.
12218 * @param {*} value The value to check.
12219 * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
12222 * _.isUndefined(void 0);
12225 * _.isUndefined(null);
12228 function isUndefined(value) {
12229 return value === undefined;
12233 * Checks if `value` is classified as a `WeakMap` object.
12239 * @param {*} value The value to check.
12240 * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
12243 * _.isWeakMap(new WeakMap);
12246 * _.isWeakMap(new Map);
12249 function isWeakMap(value) {
12250 return isObjectLike(value) && getTag(value) == weakMapTag;
12254 * Checks if `value` is classified as a `WeakSet` object.
12260 * @param {*} value The value to check.
12261 * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
12264 * _.isWeakSet(new WeakSet);
12267 * _.isWeakSet(new Set);
12270 function isWeakSet(value) {
12271 return isObjectLike(value) && baseGetTag(value) == weakSetTag;
12275 * Checks if `value` is less than `other`.
12281 * @param {*} value The value to compare.
12282 * @param {*} other The other value to compare.
12283 * @returns {boolean} Returns `true` if `value` is less than `other`,
12297 var lt = createRelationalOperation(baseLt);
12300 * Checks if `value` is less than or equal to `other`.
12306 * @param {*} value The value to compare.
12307 * @param {*} other The other value to compare.
12308 * @returns {boolean} Returns `true` if `value` is less than or equal to
12309 * `other`, else `false`.
12322 var lte = createRelationalOperation(function(value, other) {
12323 return value <= other;
12327 * Converts `value` to an array.
12333 * @param {*} value The value to convert.
12334 * @returns {Array} Returns the converted array.
12337 * _.toArray({ 'a': 1, 'b': 2 });
12340 * _.toArray('abc');
12341 * // => ['a', 'b', 'c']
12349 function toArray(value) {
12353 if (isArrayLike(value)) {
12354 return isString(value) ? stringToArray(value) : copyArray(value);
12356 if (symIterator && value[symIterator]) {
12357 return iteratorToArray(value[symIterator]());
12359 var tag = getTag(value),
12360 func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
12362 return func(value);
12366 * Converts `value` to a finite number.
12372 * @param {*} value The value to convert.
12373 * @returns {number} Returns the converted number.
12379 * _.toFinite(Number.MIN_VALUE);
12382 * _.toFinite(Infinity);
12383 * // => 1.7976931348623157e+308
12385 * _.toFinite('3.2');
12388 function toFinite(value) {
12390 return value === 0 ? value : 0;
12392 value = toNumber(value);
12393 if (value === INFINITY || value === -INFINITY) {
12394 var sign = (value < 0 ? -1 : 1);
12395 return sign * MAX_INTEGER;
12397 return value === value ? value : 0;
12401 * Converts `value` to an integer.
12403 * **Note:** This method is loosely based on
12404 * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
12410 * @param {*} value The value to convert.
12411 * @returns {number} Returns the converted integer.
12414 * _.toInteger(3.2);
12417 * _.toInteger(Number.MIN_VALUE);
12420 * _.toInteger(Infinity);
12421 * // => 1.7976931348623157e+308
12423 * _.toInteger('3.2');
12426 function toInteger(value) {
12427 var result = toFinite(value),
12428 remainder = result % 1;
12430 return result === result ? (remainder ? result - remainder : result) : 0;
12434 * Converts `value` to an integer suitable for use as the length of an
12435 * array-like object.
12437 * **Note:** This method is based on
12438 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
12444 * @param {*} value The value to convert.
12445 * @returns {number} Returns the converted integer.
12451 * _.toLength(Number.MIN_VALUE);
12454 * _.toLength(Infinity);
12457 * _.toLength('3.2');
12460 function toLength(value) {
12461 return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
12465 * Converts `value` to a number.
12471 * @param {*} value The value to process.
12472 * @returns {number} Returns the number.
12478 * _.toNumber(Number.MIN_VALUE);
12481 * _.toNumber(Infinity);
12484 * _.toNumber('3.2');
12487 function toNumber(value) {
12488 if (typeof value == 'number') {
12491 if (isSymbol(value)) {
12494 if (isObject(value)) {
12495 var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
12496 value = isObject(other) ? (other + '') : other;
12498 if (typeof value != 'string') {
12499 return value === 0 ? value : +value;
12501 value = value.replace(reTrim, '');
12502 var isBinary = reIsBinary.test(value);
12503 return (isBinary || reIsOctal.test(value))
12504 ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
12505 : (reIsBadHex.test(value) ? NAN : +value);
12509 * Converts `value` to a plain object flattening inherited enumerable string
12510 * keyed properties of `value` to own properties of the plain object.
12516 * @param {*} value The value to convert.
12517 * @returns {Object} Returns the converted plain object.
12524 * Foo.prototype.c = 3;
12526 * _.assign({ 'a': 1 }, new Foo);
12527 * // => { 'a': 1, 'b': 2 }
12529 * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
12530 * // => { 'a': 1, 'b': 2, 'c': 3 }
12532 function toPlainObject(value) {
12533 return copyObject(value, keysIn(value));
12537 * Converts `value` to a safe integer. A safe integer can be compared and
12538 * represented correctly.
12544 * @param {*} value The value to convert.
12545 * @returns {number} Returns the converted integer.
12548 * _.toSafeInteger(3.2);
12551 * _.toSafeInteger(Number.MIN_VALUE);
12554 * _.toSafeInteger(Infinity);
12555 * // => 9007199254740991
12557 * _.toSafeInteger('3.2');
12560 function toSafeInteger(value) {
12561 return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
12565 * Converts `value` to a string. An empty string is returned for `null`
12566 * and `undefined` values. The sign of `-0` is preserved.
12572 * @param {*} value The value to convert.
12573 * @returns {string} Returns the converted string.
12576 * _.toString(null);
12582 * _.toString([1, 2, 3]);
12585 function toString(value) {
12586 return value == null ? '' : baseToString(value);
12589 /*------------------------------------------------------------------------*/
12592 * Assigns own enumerable string keyed properties of source objects to the
12593 * destination object. Source objects are applied from left to right.
12594 * Subsequent sources overwrite property assignments of previous sources.
12596 * **Note:** This method mutates `object` and is loosely based on
12597 * [`Object.assign`](https://mdn.io/Object/assign).
12603 * @param {Object} object The destination object.
12604 * @param {...Object} [sources] The source objects.
12605 * @returns {Object} Returns `object`.
12617 * Foo.prototype.b = 2;
12618 * Bar.prototype.d = 4;
12620 * _.assign({ 'a': 0 }, new Foo, new Bar);
12621 * // => { 'a': 1, 'c': 3 }
12623 var assign = createAssigner(function(object, source) {
12624 if (isPrototype(source) || isArrayLike(source)) {
12625 copyObject(source, keys(source), object);
12628 for (var key in source) {
12629 if (hasOwnProperty.call(source, key)) {
12630 assignValue(object, key, source[key]);
12636 * This method is like `_.assign` except that it iterates over own and
12637 * inherited source properties.
12639 * **Note:** This method mutates `object`.
12646 * @param {Object} object The destination object.
12647 * @param {...Object} [sources] The source objects.
12648 * @returns {Object} Returns `object`.
12660 * Foo.prototype.b = 2;
12661 * Bar.prototype.d = 4;
12663 * _.assignIn({ 'a': 0 }, new Foo, new Bar);
12664 * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
12666 var assignIn = createAssigner(function(object, source) {
12667 copyObject(source, keysIn(source), object);
12671 * This method is like `_.assignIn` except that it accepts `customizer`
12672 * which is invoked to produce the assigned values. If `customizer` returns
12673 * `undefined`, assignment is handled by the method instead. The `customizer`
12674 * is invoked with five arguments: (objValue, srcValue, key, object, source).
12676 * **Note:** This method mutates `object`.
12681 * @alias extendWith
12683 * @param {Object} object The destination object.
12684 * @param {...Object} sources The source objects.
12685 * @param {Function} [customizer] The function to customize assigned values.
12686 * @returns {Object} Returns `object`.
12687 * @see _.assignWith
12690 * function customizer(objValue, srcValue) {
12691 * return _.isUndefined(objValue) ? srcValue : objValue;
12694 * var defaults = _.partialRight(_.assignInWith, customizer);
12696 * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
12697 * // => { 'a': 1, 'b': 2 }
12699 var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
12700 copyObject(source, keysIn(source), object, customizer);
12704 * This method is like `_.assign` except that it accepts `customizer`
12705 * which is invoked to produce the assigned values. If `customizer` returns
12706 * `undefined`, assignment is handled by the method instead. The `customizer`
12707 * is invoked with five arguments: (objValue, srcValue, key, object, source).
12709 * **Note:** This method mutates `object`.
12715 * @param {Object} object The destination object.
12716 * @param {...Object} sources The source objects.
12717 * @param {Function} [customizer] The function to customize assigned values.
12718 * @returns {Object} Returns `object`.
12719 * @see _.assignInWith
12722 * function customizer(objValue, srcValue) {
12723 * return _.isUndefined(objValue) ? srcValue : objValue;
12726 * var defaults = _.partialRight(_.assignWith, customizer);
12728 * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
12729 * // => { 'a': 1, 'b': 2 }
12731 var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
12732 copyObject(source, keys(source), object, customizer);
12736 * Creates an array of values corresponding to `paths` of `object`.
12742 * @param {Object} object The object to iterate over.
12743 * @param {...(string|string[])} [paths] The property paths to pick.
12744 * @returns {Array} Returns the picked values.
12747 * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
12749 * _.at(object, ['a[0].b.c', 'a[1]']);
12752 var at = flatRest(baseAt);
12755 * Creates an object that inherits from the `prototype` object. If a
12756 * `properties` object is given, its own enumerable string keyed properties
12757 * are assigned to the created object.
12763 * @param {Object} prototype The object to inherit from.
12764 * @param {Object} [properties] The properties to assign to the object.
12765 * @returns {Object} Returns the new object.
12768 * function Shape() {
12773 * function Circle() {
12774 * Shape.call(this);
12777 * Circle.prototype = _.create(Shape.prototype, {
12778 * 'constructor': Circle
12781 * var circle = new Circle;
12782 * circle instanceof Circle;
12785 * circle instanceof Shape;
12788 function create(prototype, properties) {
12789 var result = baseCreate(prototype);
12790 return properties == null ? result : baseAssign(result, properties);
12794 * Assigns own and inherited enumerable string keyed properties of source
12795 * objects to the destination object for all destination properties that
12796 * resolve to `undefined`. Source objects are applied from left to right.
12797 * Once a property is set, additional values of the same property are ignored.
12799 * **Note:** This method mutates `object`.
12805 * @param {Object} object The destination object.
12806 * @param {...Object} [sources] The source objects.
12807 * @returns {Object} Returns `object`.
12808 * @see _.defaultsDeep
12811 * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
12812 * // => { 'a': 1, 'b': 2 }
12814 var defaults = baseRest(function(args) {
12815 args.push(undefined, assignInDefaults);
12816 return apply(assignInWith, undefined, args);
12820 * This method is like `_.defaults` except that it recursively assigns
12821 * default properties.
12823 * **Note:** This method mutates `object`.
12829 * @param {Object} object The destination object.
12830 * @param {...Object} [sources] The source objects.
12831 * @returns {Object} Returns `object`.
12835 * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
12836 * // => { 'a': { 'b': 2, 'c': 3 } }
12838 var defaultsDeep = baseRest(function(args) {
12839 args.push(undefined, mergeDefaults);
12840 return apply(mergeWith, undefined, args);
12844 * This method is like `_.find` except that it returns the key of the first
12845 * element `predicate` returns truthy for instead of the element itself.
12851 * @param {Object} object The object to inspect.
12852 * @param {Function} [predicate=_.identity] The function invoked per iteration.
12853 * @returns {string|undefined} Returns the key of the matched element,
12854 * else `undefined`.
12858 * 'barney': { 'age': 36, 'active': true },
12859 * 'fred': { 'age': 40, 'active': false },
12860 * 'pebbles': { 'age': 1, 'active': true }
12863 * _.findKey(users, function(o) { return o.age < 40; });
12864 * // => 'barney' (iteration order is not guaranteed)
12866 * // The `_.matches` iteratee shorthand.
12867 * _.findKey(users, { 'age': 1, 'active': true });
12870 * // The `_.matchesProperty` iteratee shorthand.
12871 * _.findKey(users, ['active', false]);
12874 * // The `_.property` iteratee shorthand.
12875 * _.findKey(users, 'active');
12878 function findKey(object, predicate) {
12879 return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
12883 * This method is like `_.findKey` except that it iterates over elements of
12884 * a collection in the opposite order.
12890 * @param {Object} object The object to inspect.
12891 * @param {Function} [predicate=_.identity] The function invoked per iteration.
12892 * @returns {string|undefined} Returns the key of the matched element,
12893 * else `undefined`.
12897 * 'barney': { 'age': 36, 'active': true },
12898 * 'fred': { 'age': 40, 'active': false },
12899 * 'pebbles': { 'age': 1, 'active': true }
12902 * _.findLastKey(users, function(o) { return o.age < 40; });
12903 * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
12905 * // The `_.matches` iteratee shorthand.
12906 * _.findLastKey(users, { 'age': 36, 'active': true });
12909 * // The `_.matchesProperty` iteratee shorthand.
12910 * _.findLastKey(users, ['active', false]);
12913 * // The `_.property` iteratee shorthand.
12914 * _.findLastKey(users, 'active');
12917 function findLastKey(object, predicate) {
12918 return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
12922 * Iterates over own and inherited enumerable string keyed properties of an
12923 * object and invokes `iteratee` for each property. The iteratee is invoked
12924 * with three arguments: (value, key, object). Iteratee functions may exit
12925 * iteration early by explicitly returning `false`.
12931 * @param {Object} object The object to iterate over.
12932 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12933 * @returns {Object} Returns `object`.
12934 * @see _.forInRight
12942 * Foo.prototype.c = 3;
12944 * _.forIn(new Foo, function(value, key) {
12945 * console.log(key);
12947 * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
12949 function forIn(object, iteratee) {
12950 return object == null
12952 : baseFor(object, getIteratee(iteratee, 3), keysIn);
12956 * This method is like `_.forIn` except that it iterates over properties of
12957 * `object` in the opposite order.
12963 * @param {Object} object The object to iterate over.
12964 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12965 * @returns {Object} Returns `object`.
12974 * Foo.prototype.c = 3;
12976 * _.forInRight(new Foo, function(value, key) {
12977 * console.log(key);
12979 * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
12981 function forInRight(object, iteratee) {
12982 return object == null
12984 : baseForRight(object, getIteratee(iteratee, 3), keysIn);
12988 * Iterates over own enumerable string keyed properties of an object and
12989 * invokes `iteratee` for each property. The iteratee is invoked with three
12990 * arguments: (value, key, object). Iteratee functions may exit iteration
12991 * early by explicitly returning `false`.
12997 * @param {Object} object The object to iterate over.
12998 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12999 * @returns {Object} Returns `object`.
13000 * @see _.forOwnRight
13008 * Foo.prototype.c = 3;
13010 * _.forOwn(new Foo, function(value, key) {
13011 * console.log(key);
13013 * // => Logs 'a' then 'b' (iteration order is not guaranteed).
13015 function forOwn(object, iteratee) {
13016 return object && baseForOwn(object, getIteratee(iteratee, 3));
13020 * This method is like `_.forOwn` except that it iterates over properties of
13021 * `object` in the opposite order.
13027 * @param {Object} object The object to iterate over.
13028 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13029 * @returns {Object} Returns `object`.
13038 * Foo.prototype.c = 3;
13040 * _.forOwnRight(new Foo, function(value, key) {
13041 * console.log(key);
13043 * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
13045 function forOwnRight(object, iteratee) {
13046 return object && baseForOwnRight(object, getIteratee(iteratee, 3));
13050 * Creates an array of function property names from own enumerable properties
13057 * @param {Object} object The object to inspect.
13058 * @returns {Array} Returns the function names.
13059 * @see _.functionsIn
13063 * this.a = _.constant('a');
13064 * this.b = _.constant('b');
13067 * Foo.prototype.c = _.constant('c');
13069 * _.functions(new Foo);
13072 function functions(object) {
13073 return object == null ? [] : baseFunctions(object, keys(object));
13077 * Creates an array of function property names from own and inherited
13078 * enumerable properties of `object`.
13084 * @param {Object} object The object to inspect.
13085 * @returns {Array} Returns the function names.
13090 * this.a = _.constant('a');
13091 * this.b = _.constant('b');
13094 * Foo.prototype.c = _.constant('c');
13096 * _.functionsIn(new Foo);
13097 * // => ['a', 'b', 'c']
13099 function functionsIn(object) {
13100 return object == null ? [] : baseFunctions(object, keysIn(object));
13104 * Gets the value at `path` of `object`. If the resolved value is
13105 * `undefined`, the `defaultValue` is returned in its place.
13111 * @param {Object} object The object to query.
13112 * @param {Array|string} path The path of the property to get.
13113 * @param {*} [defaultValue] The value returned for `undefined` resolved values.
13114 * @returns {*} Returns the resolved value.
13117 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
13119 * _.get(object, 'a[0].b.c');
13122 * _.get(object, ['a', '0', 'b', 'c']);
13125 * _.get(object, 'a.b.c', 'default');
13128 function get(object, path, defaultValue) {
13129 var result = object == null ? undefined : baseGet(object, path);
13130 return result === undefined ? defaultValue : result;
13134 * Checks if `path` is a direct property of `object`.
13140 * @param {Object} object The object to query.
13141 * @param {Array|string} path The path to check.
13142 * @returns {boolean} Returns `true` if `path` exists, else `false`.
13145 * var object = { 'a': { 'b': 2 } };
13146 * var other = _.create({ 'a': _.create({ 'b': 2 }) });
13148 * _.has(object, 'a');
13151 * _.has(object, 'a.b');
13154 * _.has(object, ['a', 'b']);
13157 * _.has(other, 'a');
13160 function has(object, path) {
13161 return object != null && hasPath(object, path, baseHas);
13165 * Checks if `path` is a direct or inherited property of `object`.
13171 * @param {Object} object The object to query.
13172 * @param {Array|string} path The path to check.
13173 * @returns {boolean} Returns `true` if `path` exists, else `false`.
13176 * var object = _.create({ 'a': _.create({ 'b': 2 }) });
13178 * _.hasIn(object, 'a');
13181 * _.hasIn(object, 'a.b');
13184 * _.hasIn(object, ['a', 'b']);
13187 * _.hasIn(object, 'b');
13190 function hasIn(object, path) {
13191 return object != null && hasPath(object, path, baseHasIn);
13195 * Creates an object composed of the inverted keys and values of `object`.
13196 * If `object` contains duplicate values, subsequent values overwrite
13197 * property assignments of previous values.
13203 * @param {Object} object The object to invert.
13204 * @returns {Object} Returns the new inverted object.
13207 * var object = { 'a': 1, 'b': 2, 'c': 1 };
13209 * _.invert(object);
13210 * // => { '1': 'c', '2': 'b' }
13212 var invert = createInverter(function(result, value, key) {
13213 result[value] = key;
13214 }, constant(identity));
13217 * This method is like `_.invert` except that the inverted object is generated
13218 * from the results of running each element of `object` thru `iteratee`. The
13219 * corresponding inverted value of each inverted key is an array of keys
13220 * responsible for generating the inverted value. The iteratee is invoked
13221 * with one argument: (value).
13227 * @param {Object} object The object to invert.
13228 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
13229 * @returns {Object} Returns the new inverted object.
13232 * var object = { 'a': 1, 'b': 2, 'c': 1 };
13234 * _.invertBy(object);
13235 * // => { '1': ['a', 'c'], '2': ['b'] }
13237 * _.invertBy(object, function(value) {
13238 * return 'group' + value;
13240 * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
13242 var invertBy = createInverter(function(result, value, key) {
13243 if (hasOwnProperty.call(result, value)) {
13244 result[value].push(key);
13246 result[value] = [key];
13251 * Invokes the method at `path` of `object`.
13257 * @param {Object} object The object to query.
13258 * @param {Array|string} path The path of the method to invoke.
13259 * @param {...*} [args] The arguments to invoke the method with.
13260 * @returns {*} Returns the result of the invoked method.
13263 * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
13265 * _.invoke(object, 'a[0].b.c.slice', 1, 3);
13268 var invoke = baseRest(baseInvoke);
13271 * Creates an array of the own enumerable property names of `object`.
13273 * **Note:** Non-object values are coerced to objects. See the
13274 * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
13275 * for more details.
13281 * @param {Object} object The object to query.
13282 * @returns {Array} Returns the array of property names.
13290 * Foo.prototype.c = 3;
13293 * // => ['a', 'b'] (iteration order is not guaranteed)
13298 function keys(object) {
13299 return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
13303 * Creates an array of the own and inherited enumerable property names of `object`.
13305 * **Note:** Non-object values are coerced to objects.
13311 * @param {Object} object The object to query.
13312 * @returns {Array} Returns the array of property names.
13320 * Foo.prototype.c = 3;
13322 * _.keysIn(new Foo);
13323 * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
13325 function keysIn(object) {
13326 return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
13330 * The opposite of `_.mapValues`; this method creates an object with the
13331 * same values as `object` and keys generated by running each own enumerable
13332 * string keyed property of `object` thru `iteratee`. The iteratee is invoked
13333 * with three arguments: (value, key, object).
13339 * @param {Object} object The object to iterate over.
13340 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13341 * @returns {Object} Returns the new mapped object.
13345 * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
13346 * return key + value;
13348 * // => { 'a1': 1, 'b2': 2 }
13350 function mapKeys(object, iteratee) {
13352 iteratee = getIteratee(iteratee, 3);
13354 baseForOwn(object, function(value, key, object) {
13355 baseAssignValue(result, iteratee(value, key, object), value);
13361 * Creates an object with the same keys as `object` and values generated
13362 * by running each own enumerable string keyed property of `object` thru
13363 * `iteratee`. The iteratee is invoked with three arguments:
13364 * (value, key, object).
13370 * @param {Object} object The object to iterate over.
13371 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13372 * @returns {Object} Returns the new mapped object.
13377 * 'fred': { 'user': 'fred', 'age': 40 },
13378 * 'pebbles': { 'user': 'pebbles', 'age': 1 }
13381 * _.mapValues(users, function(o) { return o.age; });
13382 * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
13384 * // The `_.property` iteratee shorthand.
13385 * _.mapValues(users, 'age');
13386 * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
13388 function mapValues(object, iteratee) {
13390 iteratee = getIteratee(iteratee, 3);
13392 baseForOwn(object, function(value, key, object) {
13393 baseAssignValue(result, key, iteratee(value, key, object));
13399 * This method is like `_.assign` except that it recursively merges own and
13400 * inherited enumerable string keyed properties of source objects into the
13401 * destination object. Source properties that resolve to `undefined` are
13402 * skipped if a destination value exists. Array and plain object properties
13403 * are merged recursively. Other objects and value types are overridden by
13404 * assignment. Source objects are applied from left to right. Subsequent
13405 * sources overwrite property assignments of previous sources.
13407 * **Note:** This method mutates `object`.
13413 * @param {Object} object The destination object.
13414 * @param {...Object} [sources] The source objects.
13415 * @returns {Object} Returns `object`.
13419 * 'a': [{ 'b': 2 }, { 'd': 4 }]
13423 * 'a': [{ 'c': 3 }, { 'e': 5 }]
13426 * _.merge(object, other);
13427 * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
13429 var merge = createAssigner(function(object, source, srcIndex) {
13430 baseMerge(object, source, srcIndex);
13434 * This method is like `_.merge` except that it accepts `customizer` which
13435 * is invoked to produce the merged values of the destination and source
13436 * properties. If `customizer` returns `undefined`, merging is handled by the
13437 * method instead. The `customizer` is invoked with six arguments:
13438 * (objValue, srcValue, key, object, source, stack).
13440 * **Note:** This method mutates `object`.
13446 * @param {Object} object The destination object.
13447 * @param {...Object} sources The source objects.
13448 * @param {Function} customizer The function to customize assigned values.
13449 * @returns {Object} Returns `object`.
13452 * function customizer(objValue, srcValue) {
13453 * if (_.isArray(objValue)) {
13454 * return objValue.concat(srcValue);
13458 * var object = { 'a': [1], 'b': [2] };
13459 * var other = { 'a': [3], 'b': [4] };
13461 * _.mergeWith(object, other, customizer);
13462 * // => { 'a': [1, 3], 'b': [2, 4] }
13464 var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
13465 baseMerge(object, source, srcIndex, customizer);
13469 * The opposite of `_.pick`; this method creates an object composed of the
13470 * own and inherited enumerable property paths of `object` that are not omitted.
13472 * **Note:** This method is considerably slower than `_.pick`.
13478 * @param {Object} object The source object.
13479 * @param {...(string|string[])} [paths] The property paths to omit.
13480 * @returns {Object} Returns the new object.
13483 * var object = { 'a': 1, 'b': '2', 'c': 3 };
13485 * _.omit(object, ['a', 'c']);
13486 * // => { 'b': '2' }
13488 var omit = flatRest(function(object, paths) {
13490 if (object == null) {
13493 var bitmask = CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG;
13494 paths = arrayMap(paths, function(path) {
13495 path = castPath(path, object);
13496 bitmask |= (path.length > 1 ? CLONE_DEEP_FLAG : 0);
13500 copyObject(object, getAllKeysIn(object), result);
13501 result = baseClone(result, bitmask);
13503 var length = paths.length;
13505 baseUnset(result, paths[length]);
13511 * The opposite of `_.pickBy`; this method creates an object composed of
13512 * the own and inherited enumerable string keyed properties of `object` that
13513 * `predicate` doesn't return truthy for. The predicate is invoked with two
13514 * arguments: (value, key).
13520 * @param {Object} object The source object.
13521 * @param {Function} [predicate=_.identity] The function invoked per property.
13522 * @returns {Object} Returns the new object.
13525 * var object = { 'a': 1, 'b': '2', 'c': 3 };
13527 * _.omitBy(object, _.isNumber);
13528 * // => { 'b': '2' }
13530 function omitBy(object, predicate) {
13531 return pickBy(object, negate(getIteratee(predicate)));
13535 * Creates an object composed of the picked `object` properties.
13541 * @param {Object} object The source object.
13542 * @param {...(string|string[])} [paths] The property paths to pick.
13543 * @returns {Object} Returns the new object.
13546 * var object = { 'a': 1, 'b': '2', 'c': 3 };
13548 * _.pick(object, ['a', 'c']);
13549 * // => { 'a': 1, 'c': 3 }
13551 var pick = flatRest(function(object, paths) {
13552 return object == null ? {} : basePick(object, paths);
13556 * Creates an object composed of the `object` properties `predicate` returns
13557 * truthy for. The predicate is invoked with two arguments: (value, key).
13563 * @param {Object} object The source object.
13564 * @param {Function} [predicate=_.identity] The function invoked per property.
13565 * @returns {Object} Returns the new object.
13568 * var object = { 'a': 1, 'b': '2', 'c': 3 };
13570 * _.pickBy(object, _.isNumber);
13571 * // => { 'a': 1, 'c': 3 }
13573 function pickBy(object, predicate) {
13574 if (object == null) {
13577 var props = arrayMap(getAllKeysIn(object), function(prop) {
13580 predicate = getIteratee(predicate);
13581 return basePickBy(object, props, function(value, path) {
13582 return predicate(value, path[0]);
13587 * This method is like `_.get` except that if the resolved value is a
13588 * function it's invoked with the `this` binding of its parent object and
13589 * its result is returned.
13595 * @param {Object} object The object to query.
13596 * @param {Array|string} path The path of the property to resolve.
13597 * @param {*} [defaultValue] The value returned for `undefined` resolved values.
13598 * @returns {*} Returns the resolved value.
13601 * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
13603 * _.result(object, 'a[0].b.c1');
13606 * _.result(object, 'a[0].b.c2');
13609 * _.result(object, 'a[0].b.c3', 'default');
13612 * _.result(object, 'a[0].b.c3', _.constant('default'));
13615 function result(object, path, defaultValue) {
13616 path = castPath(path, object);
13619 length = path.length;
13621 // Ensure the loop is entered when path is empty.
13623 object = undefined;
13626 while (++index < length) {
13627 var value = object == null ? undefined : object[toKey(path[index])];
13628 if (value === undefined) {
13630 value = defaultValue;
13632 object = isFunction(value) ? value.call(object) : value;
13638 * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
13639 * it's created. Arrays are created for missing index properties while objects
13640 * are created for all other missing properties. Use `_.setWith` to customize
13643 * **Note:** This method mutates `object`.
13649 * @param {Object} object The object to modify.
13650 * @param {Array|string} path The path of the property to set.
13651 * @param {*} value The value to set.
13652 * @returns {Object} Returns `object`.
13655 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
13657 * _.set(object, 'a[0].b.c', 4);
13658 * console.log(object.a[0].b.c);
13661 * _.set(object, ['x', '0', 'y', 'z'], 5);
13662 * console.log(object.x[0].y.z);
13665 function set(object, path, value) {
13666 return object == null ? object : baseSet(object, path, value);
13670 * This method is like `_.set` except that it accepts `customizer` which is
13671 * invoked to produce the objects of `path`. If `customizer` returns `undefined`
13672 * path creation is handled by the method instead. The `customizer` is invoked
13673 * with three arguments: (nsValue, key, nsObject).
13675 * **Note:** This method mutates `object`.
13681 * @param {Object} object The object to modify.
13682 * @param {Array|string} path The path of the property to set.
13683 * @param {*} value The value to set.
13684 * @param {Function} [customizer] The function to customize assigned values.
13685 * @returns {Object} Returns `object`.
13690 * _.setWith(object, '[0][1]', 'a', Object);
13691 * // => { '0': { '1': 'a' } }
13693 function setWith(object, path, value, customizer) {
13694 customizer = typeof customizer == 'function' ? customizer : undefined;
13695 return object == null ? object : baseSet(object, path, value, customizer);
13699 * Creates an array of own enumerable string keyed-value pairs for `object`
13700 * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
13701 * entries are returned.
13708 * @param {Object} object The object to query.
13709 * @returns {Array} Returns the key-value pairs.
13717 * Foo.prototype.c = 3;
13719 * _.toPairs(new Foo);
13720 * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
13722 var toPairs = createToPairs(keys);
13725 * Creates an array of own and inherited enumerable string keyed-value pairs
13726 * for `object` which can be consumed by `_.fromPairs`. If `object` is a map
13727 * or set, its entries are returned.
13734 * @param {Object} object The object to query.
13735 * @returns {Array} Returns the key-value pairs.
13743 * Foo.prototype.c = 3;
13745 * _.toPairsIn(new Foo);
13746 * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
13748 var toPairsIn = createToPairs(keysIn);
13751 * An alternative to `_.reduce`; this method transforms `object` to a new
13752 * `accumulator` object which is the result of running each of its own
13753 * enumerable string keyed properties thru `iteratee`, with each invocation
13754 * potentially mutating the `accumulator` object. If `accumulator` is not
13755 * provided, a new object with the same `[[Prototype]]` will be used. The
13756 * iteratee is invoked with four arguments: (accumulator, value, key, object).
13757 * Iteratee functions may exit iteration early by explicitly returning `false`.
13763 * @param {Object} object The object to iterate over.
13764 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13765 * @param {*} [accumulator] The custom accumulator value.
13766 * @returns {*} Returns the accumulated value.
13769 * _.transform([2, 3, 4], function(result, n) {
13770 * result.push(n *= n);
13771 * return n % 2 == 0;
13775 * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
13776 * (result[value] || (result[value] = [])).push(key);
13778 * // => { '1': ['a', 'c'], '2': ['b'] }
13780 function transform(object, iteratee, accumulator) {
13781 var isArr = isArray(object),
13782 isArrLike = isArr || isBuffer(object) || isTypedArray(object);
13784 iteratee = getIteratee(iteratee, 4);
13785 if (accumulator == null) {
13786 var Ctor = object && object.constructor;
13788 accumulator = isArr ? new Ctor : [];
13790 else if (isObject(object)) {
13791 accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
13797 (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
13798 return iteratee(accumulator, value, index, object);
13800 return accumulator;
13804 * Removes the property at `path` of `object`.
13806 * **Note:** This method mutates `object`.
13812 * @param {Object} object The object to modify.
13813 * @param {Array|string} path The path of the property to unset.
13814 * @returns {boolean} Returns `true` if the property is deleted, else `false`.
13817 * var object = { 'a': [{ 'b': { 'c': 7 } }] };
13818 * _.unset(object, 'a[0].b.c');
13821 * console.log(object);
13822 * // => { 'a': [{ 'b': {} }] };
13824 * _.unset(object, ['a', '0', 'b', 'c']);
13827 * console.log(object);
13828 * // => { 'a': [{ 'b': {} }] };
13830 function unset(object, path) {
13831 return object == null ? true : baseUnset(object, path);
13835 * This method is like `_.set` except that accepts `updater` to produce the
13836 * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
13837 * is invoked with one argument: (value).
13839 * **Note:** This method mutates `object`.
13845 * @param {Object} object The object to modify.
13846 * @param {Array|string} path The path of the property to set.
13847 * @param {Function} updater The function to produce the updated value.
13848 * @returns {Object} Returns `object`.
13851 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
13853 * _.update(object, 'a[0].b.c', function(n) { return n * n; });
13854 * console.log(object.a[0].b.c);
13857 * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
13858 * console.log(object.x[0].y.z);
13861 function update(object, path, updater) {
13862 return object == null ? object : baseUpdate(object, path, castFunction(updater));
13866 * This method is like `_.update` except that it accepts `customizer` which is
13867 * invoked to produce the objects of `path`. If `customizer` returns `undefined`
13868 * path creation is handled by the method instead. The `customizer` is invoked
13869 * with three arguments: (nsValue, key, nsObject).
13871 * **Note:** This method mutates `object`.
13877 * @param {Object} object The object to modify.
13878 * @param {Array|string} path The path of the property to set.
13879 * @param {Function} updater The function to produce the updated value.
13880 * @param {Function} [customizer] The function to customize assigned values.
13881 * @returns {Object} Returns `object`.
13886 * _.updateWith(object, '[0][1]', _.constant('a'), Object);
13887 * // => { '0': { '1': 'a' } }
13889 function updateWith(object, path, updater, customizer) {
13890 customizer = typeof customizer == 'function' ? customizer : undefined;
13891 return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
13895 * Creates an array of the own enumerable string keyed property values of `object`.
13897 * **Note:** Non-object values are coerced to objects.
13903 * @param {Object} object The object to query.
13904 * @returns {Array} Returns the array of property values.
13912 * Foo.prototype.c = 3;
13914 * _.values(new Foo);
13915 * // => [1, 2] (iteration order is not guaranteed)
13920 function values(object) {
13921 return object == null ? [] : baseValues(object, keys(object));
13925 * Creates an array of the own and inherited enumerable string keyed property
13926 * values of `object`.
13928 * **Note:** Non-object values are coerced to objects.
13934 * @param {Object} object The object to query.
13935 * @returns {Array} Returns the array of property values.
13943 * Foo.prototype.c = 3;
13945 * _.valuesIn(new Foo);
13946 * // => [1, 2, 3] (iteration order is not guaranteed)
13948 function valuesIn(object) {
13949 return object == null ? [] : baseValues(object, keysIn(object));
13952 /*------------------------------------------------------------------------*/
13955 * Clamps `number` within the inclusive `lower` and `upper` bounds.
13961 * @param {number} number The number to clamp.
13962 * @param {number} [lower] The lower bound.
13963 * @param {number} upper The upper bound.
13964 * @returns {number} Returns the clamped number.
13967 * _.clamp(-10, -5, 5);
13970 * _.clamp(10, -5, 5);
13973 function clamp(number, lower, upper) {
13974 if (upper === undefined) {
13978 if (upper !== undefined) {
13979 upper = toNumber(upper);
13980 upper = upper === upper ? upper : 0;
13982 if (lower !== undefined) {
13983 lower = toNumber(lower);
13984 lower = lower === lower ? lower : 0;
13986 return baseClamp(toNumber(number), lower, upper);
13990 * Checks if `n` is between `start` and up to, but not including, `end`. If
13991 * `end` is not specified, it's set to `start` with `start` then set to `0`.
13992 * If `start` is greater than `end` the params are swapped to support
13999 * @param {number} number The number to check.
14000 * @param {number} [start=0] The start of the range.
14001 * @param {number} end The end of the range.
14002 * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
14003 * @see _.range, _.rangeRight
14006 * _.inRange(3, 2, 4);
14018 * _.inRange(1.2, 2);
14021 * _.inRange(5.2, 4);
14024 * _.inRange(-3, -2, -6);
14027 function inRange(number, start, end) {
14028 start = toFinite(start);
14029 if (end === undefined) {
14033 end = toFinite(end);
14035 number = toNumber(number);
14036 return baseInRange(number, start, end);
14040 * Produces a random number between the inclusive `lower` and `upper` bounds.
14041 * If only one argument is provided a number between `0` and the given number
14042 * is returned. If `floating` is `true`, or either `lower` or `upper` are
14043 * floats, a floating-point number is returned instead of an integer.
14045 * **Note:** JavaScript follows the IEEE-754 standard for resolving
14046 * floating-point values which can produce unexpected results.
14052 * @param {number} [lower=0] The lower bound.
14053 * @param {number} [upper=1] The upper bound.
14054 * @param {boolean} [floating] Specify returning a floating-point number.
14055 * @returns {number} Returns the random number.
14059 * // => an integer between 0 and 5
14062 * // => also an integer between 0 and 5
14064 * _.random(5, true);
14065 * // => a floating-point number between 0 and 5
14067 * _.random(1.2, 5.2);
14068 * // => a floating-point number between 1.2 and 5.2
14070 function random(lower, upper, floating) {
14071 if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
14072 upper = floating = undefined;
14074 if (floating === undefined) {
14075 if (typeof upper == 'boolean') {
14079 else if (typeof lower == 'boolean') {
14084 if (lower === undefined && upper === undefined) {
14089 lower = toFinite(lower);
14090 if (upper === undefined) {
14094 upper = toFinite(upper);
14097 if (lower > upper) {
14102 if (floating || lower % 1 || upper % 1) {
14103 var rand = nativeRandom();
14104 return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
14106 return baseRandom(lower, upper);
14109 /*------------------------------------------------------------------------*/
14112 * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
14118 * @param {string} [string=''] The string to convert.
14119 * @returns {string} Returns the camel cased string.
14122 * _.camelCase('Foo Bar');
14125 * _.camelCase('--foo-bar--');
14128 * _.camelCase('__FOO_BAR__');
14131 var camelCase = createCompounder(function(result, word, index) {
14132 word = word.toLowerCase();
14133 return result + (index ? capitalize(word) : word);
14137 * Converts the first character of `string` to upper case and the remaining
14144 * @param {string} [string=''] The string to capitalize.
14145 * @returns {string} Returns the capitalized string.
14148 * _.capitalize('FRED');
14151 function capitalize(string) {
14152 return upperFirst(toString(string).toLowerCase());
14156 * Deburrs `string` by converting
14157 * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
14158 * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
14159 * letters to basic Latin letters and removing
14160 * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
14166 * @param {string} [string=''] The string to deburr.
14167 * @returns {string} Returns the deburred string.
14170 * _.deburr('déjà vu');
14173 function deburr(string) {
14174 string = toString(string);
14175 return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
14179 * Checks if `string` ends with the given target string.
14185 * @param {string} [string=''] The string to inspect.
14186 * @param {string} [target] The string to search for.
14187 * @param {number} [position=string.length] The position to search up to.
14188 * @returns {boolean} Returns `true` if `string` ends with `target`,
14192 * _.endsWith('abc', 'c');
14195 * _.endsWith('abc', 'b');
14198 * _.endsWith('abc', 'b', 2);
14201 function endsWith(string, target, position) {
14202 string = toString(string);
14203 target = baseToString(target);
14205 var length = string.length;
14206 position = position === undefined
14208 : baseClamp(toInteger(position), 0, length);
14210 var end = position;
14211 position -= target.length;
14212 return position >= 0 && string.slice(position, end) == target;
14216 * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
14217 * corresponding HTML entities.
14219 * **Note:** No other characters are escaped. To escape additional
14220 * characters use a third-party library like [_he_](https://mths.be/he).
14222 * Though the ">" character is escaped for symmetry, characters like
14223 * ">" and "/" don't need escaping in HTML and have no special meaning
14224 * unless they're part of a tag or unquoted attribute value. See
14225 * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
14226 * (under "semi-related fun fact") for more details.
14228 * When working with HTML you should always
14229 * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
14236 * @param {string} [string=''] The string to escape.
14237 * @returns {string} Returns the escaped string.
14240 * _.escape('fred, barney, & pebbles');
14241 * // => 'fred, barney, & pebbles'
14243 function escape(string) {
14244 string = toString(string);
14245 return (string && reHasUnescapedHtml.test(string))
14246 ? string.replace(reUnescapedHtml, escapeHtmlChar)
14251 * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
14252 * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
14258 * @param {string} [string=''] The string to escape.
14259 * @returns {string} Returns the escaped string.
14262 * _.escapeRegExp('[lodash](https://lodash.com/)');
14263 * // => '\[lodash\]\(https://lodash\.com/\)'
14265 function escapeRegExp(string) {
14266 string = toString(string);
14267 return (string && reHasRegExpChar.test(string))
14268 ? string.replace(reRegExpChar, '\\$&')
14273 * Converts `string` to
14274 * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
14280 * @param {string} [string=''] The string to convert.
14281 * @returns {string} Returns the kebab cased string.
14284 * _.kebabCase('Foo Bar');
14287 * _.kebabCase('fooBar');
14290 * _.kebabCase('__FOO_BAR__');
14293 var kebabCase = createCompounder(function(result, word, index) {
14294 return result + (index ? '-' : '') + word.toLowerCase();
14298 * Converts `string`, as space separated words, to lower case.
14304 * @param {string} [string=''] The string to convert.
14305 * @returns {string} Returns the lower cased string.
14308 * _.lowerCase('--Foo-Bar--');
14311 * _.lowerCase('fooBar');
14314 * _.lowerCase('__FOO_BAR__');
14317 var lowerCase = createCompounder(function(result, word, index) {
14318 return result + (index ? ' ' : '') + word.toLowerCase();
14322 * Converts the first character of `string` to lower case.
14328 * @param {string} [string=''] The string to convert.
14329 * @returns {string} Returns the converted string.
14332 * _.lowerFirst('Fred');
14335 * _.lowerFirst('FRED');
14338 var lowerFirst = createCaseFirst('toLowerCase');
14341 * Pads `string` on the left and right sides if it's shorter than `length`.
14342 * Padding characters are truncated if they can't be evenly divided by `length`.
14348 * @param {string} [string=''] The string to pad.
14349 * @param {number} [length=0] The padding length.
14350 * @param {string} [chars=' '] The string used as padding.
14351 * @returns {string} Returns the padded string.
14357 * _.pad('abc', 8, '_-');
14363 function pad(string, length, chars) {
14364 string = toString(string);
14365 length = toInteger(length);
14367 var strLength = length ? stringSize(string) : 0;
14368 if (!length || strLength >= length) {
14371 var mid = (length - strLength) / 2;
14373 createPadding(nativeFloor(mid), chars) +
14375 createPadding(nativeCeil(mid), chars)
14380 * Pads `string` on the right side if it's shorter than `length`. Padding
14381 * characters are truncated if they exceed `length`.
14387 * @param {string} [string=''] The string to pad.
14388 * @param {number} [length=0] The padding length.
14389 * @param {string} [chars=' '] The string used as padding.
14390 * @returns {string} Returns the padded string.
14393 * _.padEnd('abc', 6);
14396 * _.padEnd('abc', 6, '_-');
14399 * _.padEnd('abc', 3);
14402 function padEnd(string, length, chars) {
14403 string = toString(string);
14404 length = toInteger(length);
14406 var strLength = length ? stringSize(string) : 0;
14407 return (length && strLength < length)
14408 ? (string + createPadding(length - strLength, chars))
14413 * Pads `string` on the left side if it's shorter than `length`. Padding
14414 * characters are truncated if they exceed `length`.
14420 * @param {string} [string=''] The string to pad.
14421 * @param {number} [length=0] The padding length.
14422 * @param {string} [chars=' '] The string used as padding.
14423 * @returns {string} Returns the padded string.
14426 * _.padStart('abc', 6);
14429 * _.padStart('abc', 6, '_-');
14432 * _.padStart('abc', 3);
14435 function padStart(string, length, chars) {
14436 string = toString(string);
14437 length = toInteger(length);
14439 var strLength = length ? stringSize(string) : 0;
14440 return (length && strLength < length)
14441 ? (createPadding(length - strLength, chars) + string)
14446 * Converts `string` to an integer of the specified radix. If `radix` is
14447 * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
14448 * hexadecimal, in which case a `radix` of `16` is used.
14450 * **Note:** This method aligns with the
14451 * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
14457 * @param {string} string The string to convert.
14458 * @param {number} [radix=10] The radix to interpret `value` by.
14459 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14460 * @returns {number} Returns the converted integer.
14463 * _.parseInt('08');
14466 * _.map(['6', '08', '10'], _.parseInt);
14469 function parseInt(string, radix, guard) {
14470 if (guard || radix == null) {
14472 } else if (radix) {
14475 return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);
14479 * Repeats the given string `n` times.
14485 * @param {string} [string=''] The string to repeat.
14486 * @param {number} [n=1] The number of times to repeat the string.
14487 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14488 * @returns {string} Returns the repeated string.
14491 * _.repeat('*', 3);
14494 * _.repeat('abc', 2);
14497 * _.repeat('abc', 0);
14500 function repeat(string, n, guard) {
14501 if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
14506 return baseRepeat(toString(string), n);
14510 * Replaces matches for `pattern` in `string` with `replacement`.
14512 * **Note:** This method is based on
14513 * [`String#replace`](https://mdn.io/String/replace).
14519 * @param {string} [string=''] The string to modify.
14520 * @param {RegExp|string} pattern The pattern to replace.
14521 * @param {Function|string} replacement The match replacement.
14522 * @returns {string} Returns the modified string.
14525 * _.replace('Hi Fred', 'Fred', 'Barney');
14526 * // => 'Hi Barney'
14528 function replace() {
14529 var args = arguments,
14530 string = toString(args[0]);
14532 return args.length < 3 ? string : string.replace(args[1], args[2]);
14536 * Converts `string` to
14537 * [snake case](https://en.wikipedia.org/wiki/Snake_case).
14543 * @param {string} [string=''] The string to convert.
14544 * @returns {string} Returns the snake cased string.
14547 * _.snakeCase('Foo Bar');
14550 * _.snakeCase('fooBar');
14553 * _.snakeCase('--FOO-BAR--');
14556 var snakeCase = createCompounder(function(result, word, index) {
14557 return result + (index ? '_' : '') + word.toLowerCase();
14561 * Splits `string` by `separator`.
14563 * **Note:** This method is based on
14564 * [`String#split`](https://mdn.io/String/split).
14570 * @param {string} [string=''] The string to split.
14571 * @param {RegExp|string} separator The separator pattern to split by.
14572 * @param {number} [limit] The length to truncate results to.
14573 * @returns {Array} Returns the string segments.
14576 * _.split('a-b-c', '-', 2);
14579 function split(string, separator, limit) {
14580 if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
14581 separator = limit = undefined;
14583 limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
14587 string = toString(string);
14589 typeof separator == 'string' ||
14590 (separator != null && !isRegExp(separator))
14592 separator = baseToString(separator);
14593 if (!separator && hasUnicode(string)) {
14594 return castSlice(stringToArray(string), 0, limit);
14597 return string.split(separator, limit);
14601 * Converts `string` to
14602 * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
14608 * @param {string} [string=''] The string to convert.
14609 * @returns {string} Returns the start cased string.
14612 * _.startCase('--foo-bar--');
14615 * _.startCase('fooBar');
14618 * _.startCase('__FOO_BAR__');
14621 var startCase = createCompounder(function(result, word, index) {
14622 return result + (index ? ' ' : '') + upperFirst(word);
14626 * Checks if `string` starts with the given target string.
14632 * @param {string} [string=''] The string to inspect.
14633 * @param {string} [target] The string to search for.
14634 * @param {number} [position=0] The position to search from.
14635 * @returns {boolean} Returns `true` if `string` starts with `target`,
14639 * _.startsWith('abc', 'a');
14642 * _.startsWith('abc', 'b');
14645 * _.startsWith('abc', 'b', 1);
14648 function startsWith(string, target, position) {
14649 string = toString(string);
14650 position = baseClamp(toInteger(position), 0, string.length);
14651 target = baseToString(target);
14652 return string.slice(position, position + target.length) == target;
14656 * Creates a compiled template function that can interpolate data properties
14657 * in "interpolate" delimiters, HTML-escape interpolated data properties in
14658 * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
14659 * properties may be accessed as free variables in the template. If a setting
14660 * object is given, it takes precedence over `_.templateSettings` values.
14662 * **Note:** In the development build `_.template` utilizes
14663 * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
14664 * for easier debugging.
14666 * For more information on precompiling templates see
14667 * [lodash's custom builds documentation](https://lodash.com/custom-builds).
14669 * For more information on Chrome extension sandboxes see
14670 * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
14676 * @param {string} [string=''] The template string.
14677 * @param {Object} [options={}] The options object.
14678 * @param {RegExp} [options.escape=_.templateSettings.escape]
14679 * The HTML "escape" delimiter.
14680 * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
14681 * The "evaluate" delimiter.
14682 * @param {Object} [options.imports=_.templateSettings.imports]
14683 * An object to import into the template as free variables.
14684 * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
14685 * The "interpolate" delimiter.
14686 * @param {string} [options.sourceURL='lodash.templateSources[n]']
14687 * The sourceURL of the compiled template.
14688 * @param {string} [options.variable='obj']
14689 * The data object variable name.
14690 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14691 * @returns {Function} Returns the compiled template function.
14694 * // Use the "interpolate" delimiter to create a compiled template.
14695 * var compiled = _.template('hello <%= user %>!');
14696 * compiled({ 'user': 'fred' });
14697 * // => 'hello fred!'
14699 * // Use the HTML "escape" delimiter to escape data property values.
14700 * var compiled = _.template('<b><%- value %></b>');
14701 * compiled({ 'value': '<script>' });
14702 * // => '<b><script></b>'
14704 * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
14705 * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
14706 * compiled({ 'users': ['fred', 'barney'] });
14707 * // => '<li>fred</li><li>barney</li>'
14709 * // Use the internal `print` function in "evaluate" delimiters.
14710 * var compiled = _.template('<% print("hello " + user); %>!');
14711 * compiled({ 'user': 'barney' });
14712 * // => 'hello barney!'
14714 * // Use the ES template literal delimiter as an "interpolate" delimiter.
14715 * // Disable support by replacing the "interpolate" delimiter.
14716 * var compiled = _.template('hello ${ user }!');
14717 * compiled({ 'user': 'pebbles' });
14718 * // => 'hello pebbles!'
14720 * // Use backslashes to treat delimiters as plain text.
14721 * var compiled = _.template('<%= "\\<%- value %\\>" %>');
14722 * compiled({ 'value': 'ignored' });
14723 * // => '<%- value %>'
14725 * // Use the `imports` option to import `jQuery` as `jq`.
14726 * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
14727 * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
14728 * compiled({ 'users': ['fred', 'barney'] });
14729 * // => '<li>fred</li><li>barney</li>'
14731 * // Use the `sourceURL` option to specify a custom sourceURL for the template.
14732 * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
14734 * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
14736 * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
14737 * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
14739 * // => function(data) {
14740 * // var __t, __p = '';
14741 * // __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
14745 * // Use custom template delimiters.
14746 * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
14747 * var compiled = _.template('hello {{ user }}!');
14748 * compiled({ 'user': 'mustache' });
14749 * // => 'hello mustache!'
14751 * // Use the `source` property to inline compiled templates for meaningful
14752 * // line numbers in error messages and stack traces.
14753 * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
14755 * "main": ' + _.template(mainText).source + '\
14759 function template(string, options, guard) {
14760 // Based on John Resig's `tmpl` implementation
14761 // (http://ejohn.org/blog/javascript-micro-templating/)
14762 // and Laura Doktorova's doT.js (https://github.com/olado/doT).
14763 var settings = lodash.templateSettings;
14765 if (guard && isIterateeCall(string, options, guard)) {
14766 options = undefined;
14768 string = toString(string);
14769 options = assignInWith({}, options, settings, assignInDefaults);
14771 var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults),
14772 importsKeys = keys(imports),
14773 importsValues = baseValues(imports, importsKeys);
14778 interpolate = options.interpolate || reNoMatch,
14779 source = "__p += '";
14781 // Compile the regexp to match each delimiter.
14782 var reDelimiters = RegExp(
14783 (options.escape || reNoMatch).source + '|' +
14784 interpolate.source + '|' +
14785 (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
14786 (options.evaluate || reNoMatch).source + '|$'
14789 // Use a sourceURL for easier debugging.
14790 var sourceURL = '//# sourceURL=' +
14791 ('sourceURL' in options
14792 ? options.sourceURL
14793 : ('lodash.templateSources[' + (++templateCounter) + ']')
14796 string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
14797 interpolateValue || (interpolateValue = esTemplateValue);
14799 // Escape characters that can't be included in string literals.
14800 source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
14802 // Replace delimiters with snippets.
14805 source += "' +\n__e(" + escapeValue + ") +\n'";
14807 if (evaluateValue) {
14808 isEvaluating = true;
14809 source += "';\n" + evaluateValue + ";\n__p += '";
14811 if (interpolateValue) {
14812 source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
14814 index = offset + match.length;
14816 // The JS engine embedded in Adobe products needs `match` returned in
14817 // order to produce the correct `offset` value.
14823 // If `variable` is not specified wrap a with-statement around the generated
14824 // code to add the data object to the top of the scope chain.
14825 var variable = options.variable;
14827 source = 'with (obj) {\n' + source + '\n}\n';
14829 // Cleanup code by stripping empty strings.
14830 source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
14831 .replace(reEmptyStringMiddle, '$1')
14832 .replace(reEmptyStringTrailing, '$1;');
14834 // Frame code as the function body.
14835 source = 'function(' + (variable || 'obj') + ') {\n' +
14838 : 'obj || (obj = {});\n'
14840 "var __t, __p = ''" +
14842 ? ', __e = _.escape'
14846 ? ', __j = Array.prototype.join;\n' +
14847 "function print() { __p += __j.call(arguments, '') }\n"
14853 var result = attempt(function() {
14854 return Function(importsKeys, sourceURL + 'return ' + source)
14855 .apply(undefined, importsValues);
14858 // Provide the compiled function's source by its `toString` method or
14859 // the `source` property as a convenience for inlining compiled templates.
14860 result.source = source;
14861 if (isError(result)) {
14868 * Converts `string`, as a whole, to lower case just like
14869 * [String#toLowerCase](https://mdn.io/toLowerCase).
14875 * @param {string} [string=''] The string to convert.
14876 * @returns {string} Returns the lower cased string.
14879 * _.toLower('--Foo-Bar--');
14880 * // => '--foo-bar--'
14882 * _.toLower('fooBar');
14885 * _.toLower('__FOO_BAR__');
14886 * // => '__foo_bar__'
14888 function toLower(value) {
14889 return toString(value).toLowerCase();
14893 * Converts `string`, as a whole, to upper case just like
14894 * [String#toUpperCase](https://mdn.io/toUpperCase).
14900 * @param {string} [string=''] The string to convert.
14901 * @returns {string} Returns the upper cased string.
14904 * _.toUpper('--foo-bar--');
14905 * // => '--FOO-BAR--'
14907 * _.toUpper('fooBar');
14910 * _.toUpper('__foo_bar__');
14911 * // => '__FOO_BAR__'
14913 function toUpper(value) {
14914 return toString(value).toUpperCase();
14918 * Removes leading and trailing whitespace or specified characters from `string`.
14924 * @param {string} [string=''] The string to trim.
14925 * @param {string} [chars=whitespace] The characters to trim.
14926 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14927 * @returns {string} Returns the trimmed string.
14933 * _.trim('-_-abc-_-', '_-');
14936 * _.map([' foo ', ' bar '], _.trim);
14937 * // => ['foo', 'bar']
14939 function trim(string, chars, guard) {
14940 string = toString(string);
14941 if (string && (guard || chars === undefined)) {
14942 return string.replace(reTrim, '');
14944 if (!string || !(chars = baseToString(chars))) {
14947 var strSymbols = stringToArray(string),
14948 chrSymbols = stringToArray(chars),
14949 start = charsStartIndex(strSymbols, chrSymbols),
14950 end = charsEndIndex(strSymbols, chrSymbols) + 1;
14952 return castSlice(strSymbols, start, end).join('');
14956 * Removes trailing whitespace or specified characters from `string`.
14962 * @param {string} [string=''] The string to trim.
14963 * @param {string} [chars=whitespace] The characters to trim.
14964 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14965 * @returns {string} Returns the trimmed string.
14968 * _.trimEnd(' abc ');
14971 * _.trimEnd('-_-abc-_-', '_-');
14974 function trimEnd(string, chars, guard) {
14975 string = toString(string);
14976 if (string && (guard || chars === undefined)) {
14977 return string.replace(reTrimEnd, '');
14979 if (!string || !(chars = baseToString(chars))) {
14982 var strSymbols = stringToArray(string),
14983 end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
14985 return castSlice(strSymbols, 0, end).join('');
14989 * Removes leading whitespace or specified characters from `string`.
14995 * @param {string} [string=''] The string to trim.
14996 * @param {string} [chars=whitespace] The characters to trim.
14997 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14998 * @returns {string} Returns the trimmed string.
15001 * _.trimStart(' abc ');
15004 * _.trimStart('-_-abc-_-', '_-');
15007 function trimStart(string, chars, guard) {
15008 string = toString(string);
15009 if (string && (guard || chars === undefined)) {
15010 return string.replace(reTrimStart, '');
15012 if (!string || !(chars = baseToString(chars))) {
15015 var strSymbols = stringToArray(string),
15016 start = charsStartIndex(strSymbols, stringToArray(chars));
15018 return castSlice(strSymbols, start).join('');
15022 * Truncates `string` if it's longer than the given maximum string length.
15023 * The last characters of the truncated string are replaced with the omission
15024 * string which defaults to "...".
15030 * @param {string} [string=''] The string to truncate.
15031 * @param {Object} [options={}] The options object.
15032 * @param {number} [options.length=30] The maximum string length.
15033 * @param {string} [options.omission='...'] The string to indicate text is omitted.
15034 * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
15035 * @returns {string} Returns the truncated string.
15038 * _.truncate('hi-diddly-ho there, neighborino');
15039 * // => 'hi-diddly-ho there, neighbo...'
15041 * _.truncate('hi-diddly-ho there, neighborino', {
15045 * // => 'hi-diddly-ho there,...'
15047 * _.truncate('hi-diddly-ho there, neighborino', {
15049 * 'separator': /,? +/
15051 * // => 'hi-diddly-ho there...'
15053 * _.truncate('hi-diddly-ho there, neighborino', {
15054 * 'omission': ' [...]'
15056 * // => 'hi-diddly-ho there, neig [...]'
15058 function truncate(string, options) {
15059 var length = DEFAULT_TRUNC_LENGTH,
15060 omission = DEFAULT_TRUNC_OMISSION;
15062 if (isObject(options)) {
15063 var separator = 'separator' in options ? options.separator : separator;
15064 length = 'length' in options ? toInteger(options.length) : length;
15065 omission = 'omission' in options ? baseToString(options.omission) : omission;
15067 string = toString(string);
15069 var strLength = string.length;
15070 if (hasUnicode(string)) {
15071 var strSymbols = stringToArray(string);
15072 strLength = strSymbols.length;
15074 if (length >= strLength) {
15077 var end = length - stringSize(omission);
15081 var result = strSymbols
15082 ? castSlice(strSymbols, 0, end).join('')
15083 : string.slice(0, end);
15085 if (separator === undefined) {
15086 return result + omission;
15089 end += (result.length - end);
15091 if (isRegExp(separator)) {
15092 if (string.slice(end).search(separator)) {
15094 substring = result;
15096 if (!separator.global) {
15097 separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
15099 separator.lastIndex = 0;
15100 while ((match = separator.exec(substring))) {
15101 var newEnd = match.index;
15103 result = result.slice(0, newEnd === undefined ? end : newEnd);
15105 } else if (string.indexOf(baseToString(separator), end) != end) {
15106 var index = result.lastIndexOf(separator);
15108 result = result.slice(0, index);
15111 return result + omission;
15115 * The inverse of `_.escape`; this method converts the HTML entities
15116 * `&`, `<`, `>`, `"`, and `'` in `string` to
15117 * their corresponding characters.
15119 * **Note:** No other HTML entities are unescaped. To unescape additional
15120 * HTML entities use a third-party library like [_he_](https://mths.be/he).
15126 * @param {string} [string=''] The string to unescape.
15127 * @returns {string} Returns the unescaped string.
15130 * _.unescape('fred, barney, & pebbles');
15131 * // => 'fred, barney, & pebbles'
15133 function unescape(string) {
15134 string = toString(string);
15135 return (string && reHasEscapedHtml.test(string))
15136 ? string.replace(reEscapedHtml, unescapeHtmlChar)
15141 * Converts `string`, as space separated words, to upper case.
15147 * @param {string} [string=''] The string to convert.
15148 * @returns {string} Returns the upper cased string.
15151 * _.upperCase('--foo-bar');
15154 * _.upperCase('fooBar');
15157 * _.upperCase('__foo_bar__');
15160 var upperCase = createCompounder(function(result, word, index) {
15161 return result + (index ? ' ' : '') + word.toUpperCase();
15165 * Converts the first character of `string` to upper case.
15171 * @param {string} [string=''] The string to convert.
15172 * @returns {string} Returns the converted string.
15175 * _.upperFirst('fred');
15178 * _.upperFirst('FRED');
15181 var upperFirst = createCaseFirst('toUpperCase');
15184 * Splits `string` into an array of its words.
15190 * @param {string} [string=''] The string to inspect.
15191 * @param {RegExp|string} [pattern] The pattern to match words.
15192 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
15193 * @returns {Array} Returns the words of `string`.
15196 * _.words('fred, barney, & pebbles');
15197 * // => ['fred', 'barney', 'pebbles']
15199 * _.words('fred, barney, & pebbles', /[^, ]+/g);
15200 * // => ['fred', 'barney', '&', 'pebbles']
15202 function words(string, pattern, guard) {
15203 string = toString(string);
15204 pattern = guard ? undefined : pattern;
15206 if (pattern === undefined) {
15207 return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
15209 return string.match(pattern) || [];
15212 /*------------------------------------------------------------------------*/
15215 * Attempts to invoke `func`, returning either the result or the caught error
15216 * object. Any additional arguments are provided to `func` when it's invoked.
15222 * @param {Function} func The function to attempt.
15223 * @param {...*} [args] The arguments to invoke `func` with.
15224 * @returns {*} Returns the `func` result or error object.
15227 * // Avoid throwing errors for invalid selectors.
15228 * var elements = _.attempt(function(selector) {
15229 * return document.querySelectorAll(selector);
15232 * if (_.isError(elements)) {
15236 var attempt = baseRest(function(func, args) {
15238 return apply(func, undefined, args);
15240 return isError(e) ? e : new Error(e);
15245 * Binds methods of an object to the object itself, overwriting the existing
15248 * **Note:** This method doesn't set the "length" property of bound functions.
15254 * @param {Object} object The object to bind and assign the bound methods to.
15255 * @param {...(string|string[])} methodNames The object method names to bind.
15256 * @returns {Object} Returns `object`.
15261 * 'click': function() {
15262 * console.log('clicked ' + this.label);
15266 * _.bindAll(view, ['click']);
15267 * jQuery(element).on('click', view.click);
15268 * // => Logs 'clicked docs' when clicked.
15270 var bindAll = flatRest(function(object, methodNames) {
15271 arrayEach(methodNames, function(key) {
15273 baseAssignValue(object, key, bind(object[key], object));
15279 * Creates a function that iterates over `pairs` and invokes the corresponding
15280 * function of the first predicate to return truthy. The predicate-function
15281 * pairs are invoked with the `this` binding and arguments of the created
15288 * @param {Array} pairs The predicate-function pairs.
15289 * @returns {Function} Returns the new composite function.
15292 * var func = _.cond([
15293 * [_.matches({ 'a': 1 }), _.constant('matches A')],
15294 * [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
15295 * [_.stubTrue, _.constant('no match')]
15298 * func({ 'a': 1, 'b': 2 });
15299 * // => 'matches A'
15301 * func({ 'a': 0, 'b': 1 });
15302 * // => 'matches B'
15304 * func({ 'a': '1', 'b': '2' });
15307 function cond(pairs) {
15308 var length = pairs == null ? 0 : pairs.length,
15309 toIteratee = getIteratee();
15311 pairs = !length ? [] : arrayMap(pairs, function(pair) {
15312 if (typeof pair[1] != 'function') {
15313 throw new TypeError(FUNC_ERROR_TEXT);
15315 return [toIteratee(pair[0]), pair[1]];
15318 return baseRest(function(args) {
15320 while (++index < length) {
15321 var pair = pairs[index];
15322 if (apply(pair[0], this, args)) {
15323 return apply(pair[1], this, args);
15330 * Creates a function that invokes the predicate properties of `source` with
15331 * the corresponding property values of a given object, returning `true` if
15332 * all predicates return truthy, else `false`.
15334 * **Note:** The created function is equivalent to `_.conformsTo` with
15335 * `source` partially applied.
15341 * @param {Object} source The object of property predicates to conform to.
15342 * @returns {Function} Returns the new spec function.
15346 * { 'a': 2, 'b': 1 },
15347 * { 'a': 1, 'b': 2 }
15350 * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));
15351 * // => [{ 'a': 1, 'b': 2 }]
15353 function conforms(source) {
15354 return baseConforms(baseClone(source, CLONE_DEEP_FLAG));
15358 * Creates a function that returns `value`.
15364 * @param {*} value The value to return from the new function.
15365 * @returns {Function} Returns the new constant function.
15368 * var objects = _.times(2, _.constant({ 'a': 1 }));
15370 * console.log(objects);
15371 * // => [{ 'a': 1 }, { 'a': 1 }]
15373 * console.log(objects[0] === objects[1]);
15376 function constant(value) {
15377 return function() {
15383 * Checks `value` to determine whether a default value should be returned in
15384 * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,
15391 * @param {*} value The value to check.
15392 * @param {*} defaultValue The default value.
15393 * @returns {*} Returns the resolved value.
15396 * _.defaultTo(1, 10);
15399 * _.defaultTo(undefined, 10);
15402 function defaultTo(value, defaultValue) {
15403 return (value == null || value !== value) ? defaultValue : value;
15407 * Creates a function that returns the result of invoking the given functions
15408 * with the `this` binding of the created function, where each successive
15409 * invocation is supplied the return value of the previous.
15415 * @param {...(Function|Function[])} [funcs] The functions to invoke.
15416 * @returns {Function} Returns the new composite function.
15420 * function square(n) {
15424 * var addSquare = _.flow([_.add, square]);
15428 var flow = createFlow();
15431 * This method is like `_.flow` except that it creates a function that
15432 * invokes the given functions from right to left.
15438 * @param {...(Function|Function[])} [funcs] The functions to invoke.
15439 * @returns {Function} Returns the new composite function.
15443 * function square(n) {
15447 * var addSquare = _.flowRight([square, _.add]);
15451 var flowRight = createFlow(true);
15454 * This method returns the first argument it receives.
15460 * @param {*} value Any value.
15461 * @returns {*} Returns `value`.
15464 * var object = { 'a': 1 };
15466 * console.log(_.identity(object) === object);
15469 function identity(value) {
15474 * Creates a function that invokes `func` with the arguments of the created
15475 * function. If `func` is a property name, the created function returns the
15476 * property value for a given element. If `func` is an array or object, the
15477 * created function returns `true` for elements that contain the equivalent
15478 * source properties, otherwise it returns `false`.
15484 * @param {*} [func=_.identity] The value to convert to a callback.
15485 * @returns {Function} Returns the callback.
15489 * { 'user': 'barney', 'age': 36, 'active': true },
15490 * { 'user': 'fred', 'age': 40, 'active': false }
15493 * // The `_.matches` iteratee shorthand.
15494 * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
15495 * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
15497 * // The `_.matchesProperty` iteratee shorthand.
15498 * _.filter(users, _.iteratee(['user', 'fred']));
15499 * // => [{ 'user': 'fred', 'age': 40 }]
15501 * // The `_.property` iteratee shorthand.
15502 * _.map(users, _.iteratee('user'));
15503 * // => ['barney', 'fred']
15505 * // Create custom iteratee shorthands.
15506 * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
15507 * return !_.isRegExp(func) ? iteratee(func) : function(string) {
15508 * return func.test(string);
15512 * _.filter(['abc', 'def'], /ef/);
15515 function iteratee(func) {
15516 return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));
15520 * Creates a function that performs a partial deep comparison between a given
15521 * object and `source`, returning `true` if the given object has equivalent
15522 * property values, else `false`.
15524 * **Note:** The created function is equivalent to `_.isMatch` with `source`
15525 * partially applied.
15527 * Partial comparisons will match empty array and empty object `source`
15528 * values against any array or object value, respectively. See `_.isEqual`
15529 * for a list of supported value comparisons.
15535 * @param {Object} source The object of property values to match.
15536 * @returns {Function} Returns the new spec function.
15540 * { 'a': 1, 'b': 2, 'c': 3 },
15541 * { 'a': 4, 'b': 5, 'c': 6 }
15544 * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
15545 * // => [{ 'a': 4, 'b': 5, 'c': 6 }]
15547 function matches(source) {
15548 return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
15552 * Creates a function that performs a partial deep comparison between the
15553 * value at `path` of a given object to `srcValue`, returning `true` if the
15554 * object value is equivalent, else `false`.
15556 * **Note:** Partial comparisons will match empty array and empty object
15557 * `srcValue` values against any array or object value, respectively. See
15558 * `_.isEqual` for a list of supported value comparisons.
15564 * @param {Array|string} path The path of the property to get.
15565 * @param {*} srcValue The value to match.
15566 * @returns {Function} Returns the new spec function.
15570 * { 'a': 1, 'b': 2, 'c': 3 },
15571 * { 'a': 4, 'b': 5, 'c': 6 }
15574 * _.find(objects, _.matchesProperty('a', 4));
15575 * // => { 'a': 4, 'b': 5, 'c': 6 }
15577 function matchesProperty(path, srcValue) {
15578 return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));
15582 * Creates a function that invokes the method at `path` of a given object.
15583 * Any additional arguments are provided to the invoked method.
15589 * @param {Array|string} path The path of the method to invoke.
15590 * @param {...*} [args] The arguments to invoke the method with.
15591 * @returns {Function} Returns the new invoker function.
15595 * { 'a': { 'b': _.constant(2) } },
15596 * { 'a': { 'b': _.constant(1) } }
15599 * _.map(objects, _.method('a.b'));
15602 * _.map(objects, _.method(['a', 'b']));
15605 var method = baseRest(function(path, args) {
15606 return function(object) {
15607 return baseInvoke(object, path, args);
15612 * The opposite of `_.method`; this method creates a function that invokes
15613 * the method at a given path of `object`. Any additional arguments are
15614 * provided to the invoked method.
15620 * @param {Object} object The object to query.
15621 * @param {...*} [args] The arguments to invoke the method with.
15622 * @returns {Function} Returns the new invoker function.
15625 * var array = _.times(3, _.constant),
15626 * object = { 'a': array, 'b': array, 'c': array };
15628 * _.map(['a[2]', 'c[0]'], _.methodOf(object));
15631 * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
15634 var methodOf = baseRest(function(object, args) {
15635 return function(path) {
15636 return baseInvoke(object, path, args);
15641 * Adds all own enumerable string keyed function properties of a source
15642 * object to the destination object. If `object` is a function, then methods
15643 * are added to its prototype as well.
15645 * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
15646 * avoid conflicts caused by modifying the original.
15652 * @param {Function|Object} [object=lodash] The destination object.
15653 * @param {Object} source The object of functions to add.
15654 * @param {Object} [options={}] The options object.
15655 * @param {boolean} [options.chain=true] Specify whether mixins are chainable.
15656 * @returns {Function|Object} Returns `object`.
15659 * function vowels(string) {
15660 * return _.filter(string, function(v) {
15661 * return /[aeiou]/i.test(v);
15665 * _.mixin({ 'vowels': vowels });
15666 * _.vowels('fred');
15669 * _('fred').vowels().value();
15672 * _.mixin({ 'vowels': vowels }, { 'chain': false });
15673 * _('fred').vowels();
15676 function mixin(object, source, options) {
15677 var props = keys(source),
15678 methodNames = baseFunctions(source, props);
15680 if (options == null &&
15681 !(isObject(source) && (methodNames.length || !props.length))) {
15685 methodNames = baseFunctions(source, keys(source));
15687 var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
15688 isFunc = isFunction(object);
15690 arrayEach(methodNames, function(methodName) {
15691 var func = source[methodName];
15692 object[methodName] = func;
15694 object.prototype[methodName] = function() {
15695 var chainAll = this.__chain__;
15696 if (chain || chainAll) {
15697 var result = object(this.__wrapped__),
15698 actions = result.__actions__ = copyArray(this.__actions__);
15700 actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
15701 result.__chain__ = chainAll;
15704 return func.apply(object, arrayPush([this.value()], arguments));
15713 * Reverts the `_` variable to its previous value and returns a reference to
15714 * the `lodash` function.
15720 * @returns {Function} Returns the `lodash` function.
15723 * var lodash = _.noConflict();
15725 function noConflict() {
15726 if (root._ === this) {
15733 * This method returns `undefined`.
15741 * _.times(2, _.noop);
15742 * // => [undefined, undefined]
15745 // No operation performed.
15749 * Creates a function that gets the argument at index `n`. If `n` is negative,
15750 * the nth argument from the end is returned.
15756 * @param {number} [n=0] The index of the argument to return.
15757 * @returns {Function} Returns the new pass-thru function.
15760 * var func = _.nthArg(1);
15761 * func('a', 'b', 'c', 'd');
15764 * var func = _.nthArg(-2);
15765 * func('a', 'b', 'c', 'd');
15768 function nthArg(n) {
15770 return baseRest(function(args) {
15771 return baseNth(args, n);
15776 * Creates a function that invokes `iteratees` with the arguments it receives
15777 * and returns their results.
15783 * @param {...(Function|Function[])} [iteratees=[_.identity]]
15784 * The iteratees to invoke.
15785 * @returns {Function} Returns the new function.
15788 * var func = _.over([Math.max, Math.min]);
15790 * func(1, 2, 3, 4);
15793 var over = createOver(arrayMap);
15796 * Creates a function that checks if **all** of the `predicates` return
15797 * truthy when invoked with the arguments it receives.
15803 * @param {...(Function|Function[])} [predicates=[_.identity]]
15804 * The predicates to check.
15805 * @returns {Function} Returns the new function.
15808 * var func = _.overEvery([Boolean, isFinite]);
15819 var overEvery = createOver(arrayEvery);
15822 * Creates a function that checks if **any** of the `predicates` return
15823 * truthy when invoked with the arguments it receives.
15829 * @param {...(Function|Function[])} [predicates=[_.identity]]
15830 * The predicates to check.
15831 * @returns {Function} Returns the new function.
15834 * var func = _.overSome([Boolean, isFinite]);
15845 var overSome = createOver(arraySome);
15848 * Creates a function that returns the value at `path` of a given object.
15854 * @param {Array|string} path The path of the property to get.
15855 * @returns {Function} Returns the new accessor function.
15859 * { 'a': { 'b': 2 } },
15860 * { 'a': { 'b': 1 } }
15863 * _.map(objects, _.property('a.b'));
15866 * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
15869 function property(path) {
15870 return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
15874 * The opposite of `_.property`; this method creates a function that returns
15875 * the value at a given path of `object`.
15881 * @param {Object} object The object to query.
15882 * @returns {Function} Returns the new accessor function.
15885 * var array = [0, 1, 2],
15886 * object = { 'a': array, 'b': array, 'c': array };
15888 * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
15891 * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
15894 function propertyOf(object) {
15895 return function(path) {
15896 return object == null ? undefined : baseGet(object, path);
15901 * Creates an array of numbers (positive and/or negative) progressing from
15902 * `start` up to, but not including, `end`. A step of `-1` is used if a negative
15903 * `start` is specified without an `end` or `step`. If `end` is not specified,
15904 * it's set to `start` with `start` then set to `0`.
15906 * **Note:** JavaScript follows the IEEE-754 standard for resolving
15907 * floating-point values which can produce unexpected results.
15913 * @param {number} [start=0] The start of the range.
15914 * @param {number} end The end of the range.
15915 * @param {number} [step=1] The value to increment or decrement by.
15916 * @returns {Array} Returns the range of numbers.
15917 * @see _.inRange, _.rangeRight
15921 * // => [0, 1, 2, 3]
15924 * // => [0, -1, -2, -3]
15927 * // => [1, 2, 3, 4]
15929 * _.range(0, 20, 5);
15930 * // => [0, 5, 10, 15]
15932 * _.range(0, -4, -1);
15933 * // => [0, -1, -2, -3]
15935 * _.range(1, 4, 0);
15941 var range = createRange();
15944 * This method is like `_.range` except that it populates values in
15945 * descending order.
15951 * @param {number} [start=0] The start of the range.
15952 * @param {number} end The end of the range.
15953 * @param {number} [step=1] The value to increment or decrement by.
15954 * @returns {Array} Returns the range of numbers.
15955 * @see _.inRange, _.range
15959 * // => [3, 2, 1, 0]
15961 * _.rangeRight(-4);
15962 * // => [-3, -2, -1, 0]
15964 * _.rangeRight(1, 5);
15965 * // => [4, 3, 2, 1]
15967 * _.rangeRight(0, 20, 5);
15968 * // => [15, 10, 5, 0]
15970 * _.rangeRight(0, -4, -1);
15971 * // => [-3, -2, -1, 0]
15973 * _.rangeRight(1, 4, 0);
15979 var rangeRight = createRange(true);
15982 * This method returns a new empty array.
15988 * @returns {Array} Returns the new empty array.
15991 * var arrays = _.times(2, _.stubArray);
15993 * console.log(arrays);
15996 * console.log(arrays[0] === arrays[1]);
15999 function stubArray() {
16004 * This method returns `false`.
16010 * @returns {boolean} Returns `false`.
16013 * _.times(2, _.stubFalse);
16014 * // => [false, false]
16016 function stubFalse() {
16021 * This method returns a new empty object.
16027 * @returns {Object} Returns the new empty object.
16030 * var objects = _.times(2, _.stubObject);
16032 * console.log(objects);
16035 * console.log(objects[0] === objects[1]);
16038 function stubObject() {
16043 * This method returns an empty string.
16049 * @returns {string} Returns the empty string.
16052 * _.times(2, _.stubString);
16055 function stubString() {
16060 * This method returns `true`.
16066 * @returns {boolean} Returns `true`.
16069 * _.times(2, _.stubTrue);
16070 * // => [true, true]
16072 function stubTrue() {
16077 * Invokes the iteratee `n` times, returning an array of the results of
16078 * each invocation. The iteratee is invoked with one argument; (index).
16084 * @param {number} n The number of times to invoke `iteratee`.
16085 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
16086 * @returns {Array} Returns the array of results.
16089 * _.times(3, String);
16090 * // => ['0', '1', '2']
16092 * _.times(4, _.constant(0));
16093 * // => [0, 0, 0, 0]
16095 function times(n, iteratee) {
16097 if (n < 1 || n > MAX_SAFE_INTEGER) {
16100 var index = MAX_ARRAY_LENGTH,
16101 length = nativeMin(n, MAX_ARRAY_LENGTH);
16103 iteratee = getIteratee(iteratee);
16104 n -= MAX_ARRAY_LENGTH;
16106 var result = baseTimes(length, iteratee);
16107 while (++index < n) {
16114 * Converts `value` to a property path array.
16120 * @param {*} value The value to convert.
16121 * @returns {Array} Returns the new property path array.
16124 * _.toPath('a.b.c');
16125 * // => ['a', 'b', 'c']
16127 * _.toPath('a[0].b.c');
16128 * // => ['a', '0', 'b', 'c']
16130 function toPath(value) {
16131 if (isArray(value)) {
16132 return arrayMap(value, toKey);
16134 return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
16138 * Generates a unique ID. If `prefix` is given, the ID is appended to it.
16144 * @param {string} [prefix=''] The value to prefix the ID with.
16145 * @returns {string} Returns the unique ID.
16148 * _.uniqueId('contact_');
16149 * // => 'contact_104'
16154 function uniqueId(prefix) {
16155 var id = ++idCounter;
16156 return toString(prefix) + id;
16159 /*------------------------------------------------------------------------*/
16162 * Adds two numbers.
16168 * @param {number} augend The first number in an addition.
16169 * @param {number} addend The second number in an addition.
16170 * @returns {number} Returns the total.
16176 var add = createMathOperation(function(augend, addend) {
16177 return augend + addend;
16181 * Computes `number` rounded up to `precision`.
16187 * @param {number} number The number to round up.
16188 * @param {number} [precision=0] The precision to round up to.
16189 * @returns {number} Returns the rounded up number.
16195 * _.ceil(6.004, 2);
16198 * _.ceil(6040, -2);
16201 var ceil = createRound('ceil');
16204 * Divide two numbers.
16210 * @param {number} dividend The first number in a division.
16211 * @param {number} divisor The second number in a division.
16212 * @returns {number} Returns the quotient.
16218 var divide = createMathOperation(function(dividend, divisor) {
16219 return dividend / divisor;
16223 * Computes `number` rounded down to `precision`.
16229 * @param {number} number The number to round down.
16230 * @param {number} [precision=0] The precision to round down to.
16231 * @returns {number} Returns the rounded down number.
16237 * _.floor(0.046, 2);
16240 * _.floor(4060, -2);
16243 var floor = createRound('floor');
16246 * Computes the maximum value of `array`. If `array` is empty or falsey,
16247 * `undefined` is returned.
16253 * @param {Array} array The array to iterate over.
16254 * @returns {*} Returns the maximum value.
16257 * _.max([4, 2, 8, 6]);
16263 function max(array) {
16264 return (array && array.length)
16265 ? baseExtremum(array, identity, baseGt)
16270 * This method is like `_.max` except that it accepts `iteratee` which is
16271 * invoked for each element in `array` to generate the criterion by which
16272 * the value is ranked. The iteratee is invoked with one argument: (value).
16278 * @param {Array} array The array to iterate over.
16279 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16280 * @returns {*} Returns the maximum value.
16283 * var objects = [{ 'n': 1 }, { 'n': 2 }];
16285 * _.maxBy(objects, function(o) { return o.n; });
16288 * // The `_.property` iteratee shorthand.
16289 * _.maxBy(objects, 'n');
16292 function maxBy(array, iteratee) {
16293 return (array && array.length)
16294 ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)
16299 * Computes the mean of the values in `array`.
16305 * @param {Array} array The array to iterate over.
16306 * @returns {number} Returns the mean.
16309 * _.mean([4, 2, 8, 6]);
16312 function mean(array) {
16313 return baseMean(array, identity);
16317 * This method is like `_.mean` except that it accepts `iteratee` which is
16318 * invoked for each element in `array` to generate the value to be averaged.
16319 * The iteratee is invoked with one argument: (value).
16325 * @param {Array} array The array to iterate over.
16326 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16327 * @returns {number} Returns the mean.
16330 * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
16332 * _.meanBy(objects, function(o) { return o.n; });
16335 * // The `_.property` iteratee shorthand.
16336 * _.meanBy(objects, 'n');
16339 function meanBy(array, iteratee) {
16340 return baseMean(array, getIteratee(iteratee, 2));
16344 * Computes the minimum value of `array`. If `array` is empty or falsey,
16345 * `undefined` is returned.
16351 * @param {Array} array The array to iterate over.
16352 * @returns {*} Returns the minimum value.
16355 * _.min([4, 2, 8, 6]);
16361 function min(array) {
16362 return (array && array.length)
16363 ? baseExtremum(array, identity, baseLt)
16368 * This method is like `_.min` except that it accepts `iteratee` which is
16369 * invoked for each element in `array` to generate the criterion by which
16370 * the value is ranked. The iteratee is invoked with one argument: (value).
16376 * @param {Array} array The array to iterate over.
16377 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16378 * @returns {*} Returns the minimum value.
16381 * var objects = [{ 'n': 1 }, { 'n': 2 }];
16383 * _.minBy(objects, function(o) { return o.n; });
16386 * // The `_.property` iteratee shorthand.
16387 * _.minBy(objects, 'n');
16390 function minBy(array, iteratee) {
16391 return (array && array.length)
16392 ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)
16397 * Multiply two numbers.
16403 * @param {number} multiplier The first number in a multiplication.
16404 * @param {number} multiplicand The second number in a multiplication.
16405 * @returns {number} Returns the product.
16408 * _.multiply(6, 4);
16411 var multiply = createMathOperation(function(multiplier, multiplicand) {
16412 return multiplier * multiplicand;
16416 * Computes `number` rounded to `precision`.
16422 * @param {number} number The number to round.
16423 * @param {number} [precision=0] The precision to round to.
16424 * @returns {number} Returns the rounded number.
16430 * _.round(4.006, 2);
16433 * _.round(4060, -2);
16436 var round = createRound('round');
16439 * Subtract two numbers.
16445 * @param {number} minuend The first number in a subtraction.
16446 * @param {number} subtrahend The second number in a subtraction.
16447 * @returns {number} Returns the difference.
16450 * _.subtract(6, 4);
16453 var subtract = createMathOperation(function(minuend, subtrahend) {
16454 return minuend - subtrahend;
16458 * Computes the sum of the values in `array`.
16464 * @param {Array} array The array to iterate over.
16465 * @returns {number} Returns the sum.
16468 * _.sum([4, 2, 8, 6]);
16471 function sum(array) {
16472 return (array && array.length)
16473 ? baseSum(array, identity)
16478 * This method is like `_.sum` except that it accepts `iteratee` which is
16479 * invoked for each element in `array` to generate the value to be summed.
16480 * The iteratee is invoked with one argument: (value).
16486 * @param {Array} array The array to iterate over.
16487 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16488 * @returns {number} Returns the sum.
16491 * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
16493 * _.sumBy(objects, function(o) { return o.n; });
16496 * // The `_.property` iteratee shorthand.
16497 * _.sumBy(objects, 'n');
16500 function sumBy(array, iteratee) {
16501 return (array && array.length)
16502 ? baseSum(array, getIteratee(iteratee, 2))
16506 /*------------------------------------------------------------------------*/
16508 // Add methods that return wrapped values in chain sequences.
16509 lodash.after = after;
16511 lodash.assign = assign;
16512 lodash.assignIn = assignIn;
16513 lodash.assignInWith = assignInWith;
16514 lodash.assignWith = assignWith;
16516 lodash.before = before;
16517 lodash.bind = bind;
16518 lodash.bindAll = bindAll;
16519 lodash.bindKey = bindKey;
16520 lodash.castArray = castArray;
16521 lodash.chain = chain;
16522 lodash.chunk = chunk;
16523 lodash.compact = compact;
16524 lodash.concat = concat;
16525 lodash.cond = cond;
16526 lodash.conforms = conforms;
16527 lodash.constant = constant;
16528 lodash.countBy = countBy;
16529 lodash.create = create;
16530 lodash.curry = curry;
16531 lodash.curryRight = curryRight;
16532 lodash.debounce = debounce;
16533 lodash.defaults = defaults;
16534 lodash.defaultsDeep = defaultsDeep;
16535 lodash.defer = defer;
16536 lodash.delay = delay;
16537 lodash.difference = difference;
16538 lodash.differenceBy = differenceBy;
16539 lodash.differenceWith = differenceWith;
16540 lodash.drop = drop;
16541 lodash.dropRight = dropRight;
16542 lodash.dropRightWhile = dropRightWhile;
16543 lodash.dropWhile = dropWhile;
16544 lodash.fill = fill;
16545 lodash.filter = filter;
16546 lodash.flatMap = flatMap;
16547 lodash.flatMapDeep = flatMapDeep;
16548 lodash.flatMapDepth = flatMapDepth;
16549 lodash.flatten = flatten;
16550 lodash.flattenDeep = flattenDeep;
16551 lodash.flattenDepth = flattenDepth;
16552 lodash.flip = flip;
16553 lodash.flow = flow;
16554 lodash.flowRight = flowRight;
16555 lodash.fromPairs = fromPairs;
16556 lodash.functions = functions;
16557 lodash.functionsIn = functionsIn;
16558 lodash.groupBy = groupBy;
16559 lodash.initial = initial;
16560 lodash.intersection = intersection;
16561 lodash.intersectionBy = intersectionBy;
16562 lodash.intersectionWith = intersectionWith;
16563 lodash.invert = invert;
16564 lodash.invertBy = invertBy;
16565 lodash.invokeMap = invokeMap;
16566 lodash.iteratee = iteratee;
16567 lodash.keyBy = keyBy;
16568 lodash.keys = keys;
16569 lodash.keysIn = keysIn;
16571 lodash.mapKeys = mapKeys;
16572 lodash.mapValues = mapValues;
16573 lodash.matches = matches;
16574 lodash.matchesProperty = matchesProperty;
16575 lodash.memoize = memoize;
16576 lodash.merge = merge;
16577 lodash.mergeWith = mergeWith;
16578 lodash.method = method;
16579 lodash.methodOf = methodOf;
16580 lodash.mixin = mixin;
16581 lodash.negate = negate;
16582 lodash.nthArg = nthArg;
16583 lodash.omit = omit;
16584 lodash.omitBy = omitBy;
16585 lodash.once = once;
16586 lodash.orderBy = orderBy;
16587 lodash.over = over;
16588 lodash.overArgs = overArgs;
16589 lodash.overEvery = overEvery;
16590 lodash.overSome = overSome;
16591 lodash.partial = partial;
16592 lodash.partialRight = partialRight;
16593 lodash.partition = partition;
16594 lodash.pick = pick;
16595 lodash.pickBy = pickBy;
16596 lodash.property = property;
16597 lodash.propertyOf = propertyOf;
16598 lodash.pull = pull;
16599 lodash.pullAll = pullAll;
16600 lodash.pullAllBy = pullAllBy;
16601 lodash.pullAllWith = pullAllWith;
16602 lodash.pullAt = pullAt;
16603 lodash.range = range;
16604 lodash.rangeRight = rangeRight;
16605 lodash.rearg = rearg;
16606 lodash.reject = reject;
16607 lodash.remove = remove;
16608 lodash.rest = rest;
16609 lodash.reverse = reverse;
16610 lodash.sampleSize = sampleSize;
16612 lodash.setWith = setWith;
16613 lodash.shuffle = shuffle;
16614 lodash.slice = slice;
16615 lodash.sortBy = sortBy;
16616 lodash.sortedUniq = sortedUniq;
16617 lodash.sortedUniqBy = sortedUniqBy;
16618 lodash.split = split;
16619 lodash.spread = spread;
16620 lodash.tail = tail;
16621 lodash.take = take;
16622 lodash.takeRight = takeRight;
16623 lodash.takeRightWhile = takeRightWhile;
16624 lodash.takeWhile = takeWhile;
16626 lodash.throttle = throttle;
16627 lodash.thru = thru;
16628 lodash.toArray = toArray;
16629 lodash.toPairs = toPairs;
16630 lodash.toPairsIn = toPairsIn;
16631 lodash.toPath = toPath;
16632 lodash.toPlainObject = toPlainObject;
16633 lodash.transform = transform;
16634 lodash.unary = unary;
16635 lodash.union = union;
16636 lodash.unionBy = unionBy;
16637 lodash.unionWith = unionWith;
16638 lodash.uniq = uniq;
16639 lodash.uniqBy = uniqBy;
16640 lodash.uniqWith = uniqWith;
16641 lodash.unset = unset;
16642 lodash.unzip = unzip;
16643 lodash.unzipWith = unzipWith;
16644 lodash.update = update;
16645 lodash.updateWith = updateWith;
16646 lodash.values = values;
16647 lodash.valuesIn = valuesIn;
16648 lodash.without = without;
16649 lodash.words = words;
16650 lodash.wrap = wrap;
16652 lodash.xorBy = xorBy;
16653 lodash.xorWith = xorWith;
16655 lodash.zipObject = zipObject;
16656 lodash.zipObjectDeep = zipObjectDeep;
16657 lodash.zipWith = zipWith;
16660 lodash.entries = toPairs;
16661 lodash.entriesIn = toPairsIn;
16662 lodash.extend = assignIn;
16663 lodash.extendWith = assignInWith;
16665 // Add methods to `lodash.prototype`.
16666 mixin(lodash, lodash);
16668 /*------------------------------------------------------------------------*/
16670 // Add methods that return unwrapped values in chain sequences.
16672 lodash.attempt = attempt;
16673 lodash.camelCase = camelCase;
16674 lodash.capitalize = capitalize;
16675 lodash.ceil = ceil;
16676 lodash.clamp = clamp;
16677 lodash.clone = clone;
16678 lodash.cloneDeep = cloneDeep;
16679 lodash.cloneDeepWith = cloneDeepWith;
16680 lodash.cloneWith = cloneWith;
16681 lodash.conformsTo = conformsTo;
16682 lodash.deburr = deburr;
16683 lodash.defaultTo = defaultTo;
16684 lodash.divide = divide;
16685 lodash.endsWith = endsWith;
16687 lodash.escape = escape;
16688 lodash.escapeRegExp = escapeRegExp;
16689 lodash.every = every;
16690 lodash.find = find;
16691 lodash.findIndex = findIndex;
16692 lodash.findKey = findKey;
16693 lodash.findLast = findLast;
16694 lodash.findLastIndex = findLastIndex;
16695 lodash.findLastKey = findLastKey;
16696 lodash.floor = floor;
16697 lodash.forEach = forEach;
16698 lodash.forEachRight = forEachRight;
16699 lodash.forIn = forIn;
16700 lodash.forInRight = forInRight;
16701 lodash.forOwn = forOwn;
16702 lodash.forOwnRight = forOwnRight;
16707 lodash.hasIn = hasIn;
16708 lodash.head = head;
16709 lodash.identity = identity;
16710 lodash.includes = includes;
16711 lodash.indexOf = indexOf;
16712 lodash.inRange = inRange;
16713 lodash.invoke = invoke;
16714 lodash.isArguments = isArguments;
16715 lodash.isArray = isArray;
16716 lodash.isArrayBuffer = isArrayBuffer;
16717 lodash.isArrayLike = isArrayLike;
16718 lodash.isArrayLikeObject = isArrayLikeObject;
16719 lodash.isBoolean = isBoolean;
16720 lodash.isBuffer = isBuffer;
16721 lodash.isDate = isDate;
16722 lodash.isElement = isElement;
16723 lodash.isEmpty = isEmpty;
16724 lodash.isEqual = isEqual;
16725 lodash.isEqualWith = isEqualWith;
16726 lodash.isError = isError;
16727 lodash.isFinite = isFinite;
16728 lodash.isFunction = isFunction;
16729 lodash.isInteger = isInteger;
16730 lodash.isLength = isLength;
16731 lodash.isMap = isMap;
16732 lodash.isMatch = isMatch;
16733 lodash.isMatchWith = isMatchWith;
16734 lodash.isNaN = isNaN;
16735 lodash.isNative = isNative;
16736 lodash.isNil = isNil;
16737 lodash.isNull = isNull;
16738 lodash.isNumber = isNumber;
16739 lodash.isObject = isObject;
16740 lodash.isObjectLike = isObjectLike;
16741 lodash.isPlainObject = isPlainObject;
16742 lodash.isRegExp = isRegExp;
16743 lodash.isSafeInteger = isSafeInteger;
16744 lodash.isSet = isSet;
16745 lodash.isString = isString;
16746 lodash.isSymbol = isSymbol;
16747 lodash.isTypedArray = isTypedArray;
16748 lodash.isUndefined = isUndefined;
16749 lodash.isWeakMap = isWeakMap;
16750 lodash.isWeakSet = isWeakSet;
16751 lodash.join = join;
16752 lodash.kebabCase = kebabCase;
16753 lodash.last = last;
16754 lodash.lastIndexOf = lastIndexOf;
16755 lodash.lowerCase = lowerCase;
16756 lodash.lowerFirst = lowerFirst;
16760 lodash.maxBy = maxBy;
16761 lodash.mean = mean;
16762 lodash.meanBy = meanBy;
16764 lodash.minBy = minBy;
16765 lodash.stubArray = stubArray;
16766 lodash.stubFalse = stubFalse;
16767 lodash.stubObject = stubObject;
16768 lodash.stubString = stubString;
16769 lodash.stubTrue = stubTrue;
16770 lodash.multiply = multiply;
16772 lodash.noConflict = noConflict;
16773 lodash.noop = noop;
16776 lodash.padEnd = padEnd;
16777 lodash.padStart = padStart;
16778 lodash.parseInt = parseInt;
16779 lodash.random = random;
16780 lodash.reduce = reduce;
16781 lodash.reduceRight = reduceRight;
16782 lodash.repeat = repeat;
16783 lodash.replace = replace;
16784 lodash.result = result;
16785 lodash.round = round;
16786 lodash.runInContext = runInContext;
16787 lodash.sample = sample;
16788 lodash.size = size;
16789 lodash.snakeCase = snakeCase;
16790 lodash.some = some;
16791 lodash.sortedIndex = sortedIndex;
16792 lodash.sortedIndexBy = sortedIndexBy;
16793 lodash.sortedIndexOf = sortedIndexOf;
16794 lodash.sortedLastIndex = sortedLastIndex;
16795 lodash.sortedLastIndexBy = sortedLastIndexBy;
16796 lodash.sortedLastIndexOf = sortedLastIndexOf;
16797 lodash.startCase = startCase;
16798 lodash.startsWith = startsWith;
16799 lodash.subtract = subtract;
16801 lodash.sumBy = sumBy;
16802 lodash.template = template;
16803 lodash.times = times;
16804 lodash.toFinite = toFinite;
16805 lodash.toInteger = toInteger;
16806 lodash.toLength = toLength;
16807 lodash.toLower = toLower;
16808 lodash.toNumber = toNumber;
16809 lodash.toSafeInteger = toSafeInteger;
16810 lodash.toString = toString;
16811 lodash.toUpper = toUpper;
16812 lodash.trim = trim;
16813 lodash.trimEnd = trimEnd;
16814 lodash.trimStart = trimStart;
16815 lodash.truncate = truncate;
16816 lodash.unescape = unescape;
16817 lodash.uniqueId = uniqueId;
16818 lodash.upperCase = upperCase;
16819 lodash.upperFirst = upperFirst;
16822 lodash.each = forEach;
16823 lodash.eachRight = forEachRight;
16824 lodash.first = head;
16826 mixin(lodash, (function() {
16828 baseForOwn(lodash, function(func, methodName) {
16829 if (!hasOwnProperty.call(lodash.prototype, methodName)) {
16830 source[methodName] = func;
16834 }()), { 'chain': false });
16836 /*------------------------------------------------------------------------*/
16839 * The semantic version number.
16845 lodash.VERSION = VERSION;
16847 // Assign default placeholders.
16848 arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
16849 lodash[methodName].placeholder = lodash;
16852 // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
16853 arrayEach(['drop', 'take'], function(methodName, index) {
16854 LazyWrapper.prototype[methodName] = function(n) {
16855 var filtered = this.__filtered__;
16856 if (filtered && !index) {
16857 return new LazyWrapper(this);
16859 n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
16861 var result = this.clone();
16863 result.__takeCount__ = nativeMin(n, result.__takeCount__);
16865 result.__views__.push({
16866 'size': nativeMin(n, MAX_ARRAY_LENGTH),
16867 'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
16873 LazyWrapper.prototype[methodName + 'Right'] = function(n) {
16874 return this.reverse()[methodName](n).reverse();
16878 // Add `LazyWrapper` methods that accept an `iteratee` value.
16879 arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
16880 var type = index + 1,
16881 isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
16883 LazyWrapper.prototype[methodName] = function(iteratee) {
16884 var result = this.clone();
16885 result.__iteratees__.push({
16886 'iteratee': getIteratee(iteratee, 3),
16889 result.__filtered__ = result.__filtered__ || isFilter;
16894 // Add `LazyWrapper` methods for `_.head` and `_.last`.
16895 arrayEach(['head', 'last'], function(methodName, index) {
16896 var takeName = 'take' + (index ? 'Right' : '');
16898 LazyWrapper.prototype[methodName] = function() {
16899 return this[takeName](1).value()[0];
16903 // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
16904 arrayEach(['initial', 'tail'], function(methodName, index) {
16905 var dropName = 'drop' + (index ? '' : 'Right');
16907 LazyWrapper.prototype[methodName] = function() {
16908 return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
16912 LazyWrapper.prototype.compact = function() {
16913 return this.filter(identity);
16916 LazyWrapper.prototype.find = function(predicate) {
16917 return this.filter(predicate).head();
16920 LazyWrapper.prototype.findLast = function(predicate) {
16921 return this.reverse().find(predicate);
16924 LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
16925 if (typeof path == 'function') {
16926 return new LazyWrapper(this);
16928 return this.map(function(value) {
16929 return baseInvoke(value, path, args);
16933 LazyWrapper.prototype.reject = function(predicate) {
16934 return this.filter(negate(getIteratee(predicate)));
16937 LazyWrapper.prototype.slice = function(start, end) {
16938 start = toInteger(start);
16941 if (result.__filtered__ && (start > 0 || end < 0)) {
16942 return new LazyWrapper(result);
16945 result = result.takeRight(-start);
16946 } else if (start) {
16947 result = result.drop(start);
16949 if (end !== undefined) {
16950 end = toInteger(end);
16951 result = end < 0 ? result.dropRight(-end) : result.take(end - start);
16956 LazyWrapper.prototype.takeRightWhile = function(predicate) {
16957 return this.reverse().takeWhile(predicate).reverse();
16960 LazyWrapper.prototype.toArray = function() {
16961 return this.take(MAX_ARRAY_LENGTH);
16964 // Add `LazyWrapper` methods to `lodash.prototype`.
16965 baseForOwn(LazyWrapper.prototype, function(func, methodName) {
16966 var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
16967 isTaker = /^(?:head|last)$/.test(methodName),
16968 lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
16969 retUnwrapped = isTaker || /^find/.test(methodName);
16974 lodash.prototype[methodName] = function() {
16975 var value = this.__wrapped__,
16976 args = isTaker ? [1] : arguments,
16977 isLazy = value instanceof LazyWrapper,
16978 iteratee = args[0],
16979 useLazy = isLazy || isArray(value);
16981 var interceptor = function(value) {
16982 var result = lodashFunc.apply(lodash, arrayPush([value], args));
16983 return (isTaker && chainAll) ? result[0] : result;
16986 if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
16987 // Avoid lazy use if the iteratee has a "length" value other than `1`.
16988 isLazy = useLazy = false;
16990 var chainAll = this.__chain__,
16991 isHybrid = !!this.__actions__.length,
16992 isUnwrapped = retUnwrapped && !chainAll,
16993 onlyLazy = isLazy && !isHybrid;
16995 if (!retUnwrapped && useLazy) {
16996 value = onlyLazy ? value : new LazyWrapper(this);
16997 var result = func.apply(value, args);
16998 result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
16999 return new LodashWrapper(result, chainAll);
17001 if (isUnwrapped && onlyLazy) {
17002 return func.apply(this, args);
17004 result = this.thru(interceptor);
17005 return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
17009 // Add `Array` methods to `lodash.prototype`.
17010 arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
17011 var func = arrayProto[methodName],
17012 chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
17013 retUnwrapped = /^(?:pop|shift)$/.test(methodName);
17015 lodash.prototype[methodName] = function() {
17016 var args = arguments;
17017 if (retUnwrapped && !this.__chain__) {
17018 var value = this.value();
17019 return func.apply(isArray(value) ? value : [], args);
17021 return this[chainName](function(value) {
17022 return func.apply(isArray(value) ? value : [], args);
17027 // Map minified method names to their real names.
17028 baseForOwn(LazyWrapper.prototype, function(func, methodName) {
17029 var lodashFunc = lodash[methodName];
17031 var key = (lodashFunc.name + ''),
17032 names = realNames[key] || (realNames[key] = []);
17034 names.push({ 'name': methodName, 'func': lodashFunc });
17038 realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{
17043 // Add methods to `LazyWrapper`.
17044 LazyWrapper.prototype.clone = lazyClone;
17045 LazyWrapper.prototype.reverse = lazyReverse;
17046 LazyWrapper.prototype.value = lazyValue;
17048 // Add chain sequence methods to the `lodash` wrapper.
17049 lodash.prototype.at = wrapperAt;
17050 lodash.prototype.chain = wrapperChain;
17051 lodash.prototype.commit = wrapperCommit;
17052 lodash.prototype.next = wrapperNext;
17053 lodash.prototype.plant = wrapperPlant;
17054 lodash.prototype.reverse = wrapperReverse;
17055 lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
17057 // Add lazy aliases.
17058 lodash.prototype.first = lodash.prototype.head;
17061 lodash.prototype[symIterator] = wrapperToIterator;
17066 /*--------------------------------------------------------------------------*/
17069 var _ = runInContext();
17071 // Some AMD build optimizers, like r.js, check for condition patterns like:
17072 if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
17073 // Expose Lodash on the global object to prevent errors when Lodash is
17074 // loaded by a script tag in the presence of an AMD loader.
17075 // See http://requirejs.org/docs/errors.html#mismatch for more details.
17076 // Use `_.noConflict` to remove Lodash from the global object.
17079 // Define as an anonymous module so, through path mapping, it can be
17080 // referenced as the "underscore" module.
17081 define(function() {
17085 // Check for `exports` after `define` in case a build optimizer adds it.
17086 else if (freeModule) {
17087 // Export for Node.js.
17088 (freeModule.exports = _)._ = _;
17089 // Export for CommonJS support.
17093 // Export to the global object.
17096 }.call(commonjsGlobal));
17099 function osmIsInterestingTag(key) {
17100 return key !== 'attribution' &&
17101 key !== 'created_by' &&
17102 key !== 'source' &&
17104 key.indexOf('tiger:') !== 0;
17109 var osmOneWayTags = {
17111 'chair_lift': true,
17112 'mixed_lift': true,
17117 'magic_carpet': true,
17122 'motorway_link': true
17128 'piste:halfpipe': true
17142 var osmPavedTags = {
17153 var dataWikipedia = [
17270 "беларуская (тарашкевіца)",
17271 "беларуская (тарашкевіца)",
17311 "বিষ্ণুপ্রিয়া মণিপুরী",
17340 "Chavacano de Zamboanga",
17341 "Chavacano de Zamboanga",
17345 "Min Dong Chinese",
17386 "Nēhiyawēwin / ᓀᐦᐃᔭᐍᐏᐣ",
17406 "словѣньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ",
17460 "Emiliano-Romagnolo",
17461 "emiliàn e rumagnòl",
17516 "Na Vosa Vakaviti",
17535 "Northern Frisian",
17586 "गोंयची कोंकणी / Gõychi Konknni",
17666 "Bahasa Indonesia",
17706 "ᐃᓄᒃᑎᑐᑦ/inuktitut",
17715 "Jamaican Creole English",
17791 "къарачай-малкъар",
17931 "Baso Minangkabau",
18030 "Norwegian Nynorsk",
18051 "Sesotho sa Leboa",
18115 "Pennsylvania German",
18130 "Norfuk / Pitkern",
18131 "Norfuk / Pitkern",
18256 "srpskohrvatski / српскохрватски",
18320 "Saterland Frisian",
18446 "ئۇيغۇرچە / Uyghurche",
18461 "oʻzbekcha/ўзбекча",
18555 "Classical Chinese",
18560 "Chinese (Min Nan)",
18576 var dataFeatureIcons = {
18577 "circle-stroked-24": {"x":0,"y":0,"width":24,"height":24},
18578 "circle-stroked-18": {"x":24,"y":0,"width":18,"height":18},
18579 "circle-stroked-12": {"x":42,"y":0,"width":12,"height":12},
18580 "circle-24": {"x":54,"y":0,"width":24,"height":24},
18581 "circle-18": {"x":78,"y":0,"width":18,"height":18},
18582 "circle-12": {"x":96,"y":0,"width":12,"height":12},
18583 "square-stroked-24": {"x":108,"y":0,"width":24,"height":24},
18584 "square-stroked-18": {"x":132,"y":0,"width":18,"height":18},
18585 "square-stroked-12": {"x":150,"y":0,"width":12,"height":12},
18586 "square-24": {"x":162,"y":0,"width":24,"height":24},
18587 "square-18": {"x":186,"y":0,"width":18,"height":18},
18588 "square-12": {"x":204,"y":0,"width":12,"height":12},
18589 "triangle-stroked-24": {"x":216,"y":0,"width":24,"height":24},
18590 "triangle-stroked-18": {"x":240,"y":0,"width":18,"height":18},
18591 "triangle-stroked-12": {"x":258,"y":0,"width":12,"height":12},
18592 "triangle-24": {"x":0,"y":24,"width":24,"height":24},
18593 "triangle-18": {"x":24,"y":24,"width":18,"height":18},
18594 "triangle-12": {"x":42,"y":24,"width":12,"height":12},
18595 "star-stroked-24": {"x":54,"y":24,"width":24,"height":24},
18596 "star-stroked-18": {"x":78,"y":24,"width":18,"height":18},
18597 "star-stroked-12": {"x":96,"y":24,"width":12,"height":12},
18598 "star-24": {"x":108,"y":24,"width":24,"height":24},
18599 "star-18": {"x":132,"y":24,"width":18,"height":18},
18600 "star-12": {"x":150,"y":24,"width":12,"height":12},
18601 "cross-24": {"x":162,"y":24,"width":24,"height":24},
18602 "cross-18": {"x":186,"y":24,"width":18,"height":18},
18603 "cross-12": {"x":204,"y":24,"width":12,"height":12},
18604 "marker-stroked-24": {"x":216,"y":24,"width":24,"height":24},
18605 "marker-stroked-18": {"x":240,"y":24,"width":18,"height":18},
18606 "marker-stroked-12": {"x":258,"y":24,"width":12,"height":12},
18607 "marker-24": {"x":0,"y":48,"width":24,"height":24},
18608 "marker-18": {"x":24,"y":48,"width":18,"height":18},
18609 "marker-12": {"x":42,"y":48,"width":12,"height":12},
18610 "religious-jewish-24": {"x":54,"y":48,"width":24,"height":24},
18611 "religious-jewish-18": {"x":78,"y":48,"width":18,"height":18},
18612 "religious-jewish-12": {"x":96,"y":48,"width":12,"height":12},
18613 "religious-christian-24": {"x":108,"y":48,"width":24,"height":24},
18614 "religious-christian-18": {"x":132,"y":48,"width":18,"height":18},
18615 "religious-christian-12": {"x":150,"y":48,"width":12,"height":12},
18616 "religious-muslim-24": {"x":162,"y":48,"width":24,"height":24},
18617 "religious-muslim-18": {"x":186,"y":48,"width":18,"height":18},
18618 "religious-muslim-12": {"x":204,"y":48,"width":12,"height":12},
18619 "cemetery-24": {"x":216,"y":48,"width":24,"height":24},
18620 "cemetery-18": {"x":240,"y":48,"width":18,"height":18},
18621 "cemetery-12": {"x":258,"y":48,"width":12,"height":12},
18622 "rocket-24": {"x":0,"y":72,"width":24,"height":24},
18623 "rocket-18": {"x":24,"y":72,"width":18,"height":18},
18624 "rocket-12": {"x":42,"y":72,"width":12,"height":12},
18625 "airport-24": {"x":54,"y":72,"width":24,"height":24},
18626 "airport-18": {"x":78,"y":72,"width":18,"height":18},
18627 "airport-12": {"x":96,"y":72,"width":12,"height":12},
18628 "heliport-24": {"x":108,"y":72,"width":24,"height":24},
18629 "heliport-18": {"x":132,"y":72,"width":18,"height":18},
18630 "heliport-12": {"x":150,"y":72,"width":12,"height":12},
18631 "rail-24": {"x":162,"y":72,"width":24,"height":24},
18632 "rail-18": {"x":186,"y":72,"width":18,"height":18},
18633 "rail-12": {"x":204,"y":72,"width":12,"height":12},
18634 "rail-metro-24": {"x":216,"y":72,"width":24,"height":24},
18635 "rail-metro-18": {"x":240,"y":72,"width":18,"height":18},
18636 "rail-metro-12": {"x":258,"y":72,"width":12,"height":12},
18637 "rail-light-24": {"x":0,"y":96,"width":24,"height":24},
18638 "rail-light-18": {"x":24,"y":96,"width":18,"height":18},
18639 "rail-light-12": {"x":42,"y":96,"width":12,"height":12},
18640 "bus-24": {"x":54,"y":96,"width":24,"height":24},
18641 "bus-18": {"x":78,"y":96,"width":18,"height":18},
18642 "bus-12": {"x":96,"y":96,"width":12,"height":12},
18643 "fuel-24": {"x":108,"y":96,"width":24,"height":24},
18644 "fuel-18": {"x":132,"y":96,"width":18,"height":18},
18645 "fuel-12": {"x":150,"y":96,"width":12,"height":12},
18646 "parking-24": {"x":162,"y":96,"width":24,"height":24},
18647 "parking-18": {"x":186,"y":96,"width":18,"height":18},
18648 "parking-12": {"x":204,"y":96,"width":12,"height":12},
18649 "parking-garage-24": {"x":216,"y":96,"width":24,"height":24},
18650 "parking-garage-18": {"x":240,"y":96,"width":18,"height":18},
18651 "parking-garage-12": {"x":258,"y":96,"width":12,"height":12},
18652 "airfield-24": {"x":0,"y":120,"width":24,"height":24},
18653 "airfield-18": {"x":24,"y":120,"width":18,"height":18},
18654 "airfield-12": {"x":42,"y":120,"width":12,"height":12},
18655 "roadblock-24": {"x":54,"y":120,"width":24,"height":24},
18656 "roadblock-18": {"x":78,"y":120,"width":18,"height":18},
18657 "roadblock-12": {"x":96,"y":120,"width":12,"height":12},
18658 "ferry-24": {"x":108,"y":120,"width":24,"height":24},
18659 "ferry-18": {"x":132,"y":120,"width":18,"height":18},
18660 "ferry-12": {"x":150,"y":120,"width":12,"height":12},
18661 "harbor-24": {"x":162,"y":120,"width":24,"height":24},
18662 "harbor-18": {"x":186,"y":120,"width":18,"height":18},
18663 "harbor-12": {"x":204,"y":120,"width":12,"height":12},
18664 "bicycle-24": {"x":216,"y":120,"width":24,"height":24},
18665 "bicycle-18": {"x":240,"y":120,"width":18,"height":18},
18666 "bicycle-12": {"x":258,"y":120,"width":12,"height":12},
18667 "park-24": {"x":0,"y":144,"width":24,"height":24},
18668 "park-18": {"x":24,"y":144,"width":18,"height":18},
18669 "park-12": {"x":42,"y":144,"width":12,"height":12},
18670 "park2-24": {"x":54,"y":144,"width":24,"height":24},
18671 "park2-18": {"x":78,"y":144,"width":18,"height":18},
18672 "park2-12": {"x":96,"y":144,"width":12,"height":12},
18673 "museum-24": {"x":108,"y":144,"width":24,"height":24},
18674 "museum-18": {"x":132,"y":144,"width":18,"height":18},
18675 "museum-12": {"x":150,"y":144,"width":12,"height":12},
18676 "lodging-24": {"x":162,"y":144,"width":24,"height":24},
18677 "lodging-18": {"x":186,"y":144,"width":18,"height":18},
18678 "lodging-12": {"x":204,"y":144,"width":12,"height":12},
18679 "monument-24": {"x":216,"y":144,"width":24,"height":24},
18680 "monument-18": {"x":240,"y":144,"width":18,"height":18},
18681 "monument-12": {"x":258,"y":144,"width":12,"height":12},
18682 "zoo-24": {"x":0,"y":168,"width":24,"height":24},
18683 "zoo-18": {"x":24,"y":168,"width":18,"height":18},
18684 "zoo-12": {"x":42,"y":168,"width":12,"height":12},
18685 "garden-24": {"x":54,"y":168,"width":24,"height":24},
18686 "garden-18": {"x":78,"y":168,"width":18,"height":18},
18687 "garden-12": {"x":96,"y":168,"width":12,"height":12},
18688 "campsite-24": {"x":108,"y":168,"width":24,"height":24},
18689 "campsite-18": {"x":132,"y":168,"width":18,"height":18},
18690 "campsite-12": {"x":150,"y":168,"width":12,"height":12},
18691 "theatre-24": {"x":162,"y":168,"width":24,"height":24},
18692 "theatre-18": {"x":186,"y":168,"width":18,"height":18},
18693 "theatre-12": {"x":204,"y":168,"width":12,"height":12},
18694 "art-gallery-24": {"x":216,"y":168,"width":24,"height":24},
18695 "art-gallery-18": {"x":240,"y":168,"width":18,"height":18},
18696 "art-gallery-12": {"x":258,"y":168,"width":12,"height":12},
18697 "pitch-24": {"x":0,"y":192,"width":24,"height":24},
18698 "pitch-18": {"x":24,"y":192,"width":18,"height":18},
18699 "pitch-12": {"x":42,"y":192,"width":12,"height":12},
18700 "soccer-24": {"x":54,"y":192,"width":24,"height":24},
18701 "soccer-18": {"x":78,"y":192,"width":18,"height":18},
18702 "soccer-12": {"x":96,"y":192,"width":12,"height":12},
18703 "america-football-24": {"x":108,"y":192,"width":24,"height":24},
18704 "america-football-18": {"x":132,"y":192,"width":18,"height":18},
18705 "america-football-12": {"x":150,"y":192,"width":12,"height":12},
18706 "tennis-24": {"x":162,"y":192,"width":24,"height":24},
18707 "tennis-18": {"x":186,"y":192,"width":18,"height":18},
18708 "tennis-12": {"x":204,"y":192,"width":12,"height":12},
18709 "basketball-24": {"x":216,"y":192,"width":24,"height":24},
18710 "basketball-18": {"x":240,"y":192,"width":18,"height":18},
18711 "basketball-12": {"x":258,"y":192,"width":12,"height":12},
18712 "baseball-24": {"x":0,"y":216,"width":24,"height":24},
18713 "baseball-18": {"x":24,"y":216,"width":18,"height":18},
18714 "baseball-12": {"x":42,"y":216,"width":12,"height":12},
18715 "golf-24": {"x":54,"y":216,"width":24,"height":24},
18716 "golf-18": {"x":78,"y":216,"width":18,"height":18},
18717 "golf-12": {"x":96,"y":216,"width":12,"height":12},
18718 "swimming-24": {"x":108,"y":216,"width":24,"height":24},
18719 "swimming-18": {"x":132,"y":216,"width":18,"height":18},
18720 "swimming-12": {"x":150,"y":216,"width":12,"height":12},
18721 "cricket-24": {"x":162,"y":216,"width":24,"height":24},
18722 "cricket-18": {"x":186,"y":216,"width":18,"height":18},
18723 "cricket-12": {"x":204,"y":216,"width":12,"height":12},
18724 "skiing-24": {"x":216,"y":216,"width":24,"height":24},
18725 "skiing-18": {"x":240,"y":216,"width":18,"height":18},
18726 "skiing-12": {"x":258,"y":216,"width":12,"height":12},
18727 "school-24": {"x":0,"y":240,"width":24,"height":24},
18728 "school-18": {"x":24,"y":240,"width":18,"height":18},
18729 "school-12": {"x":42,"y":240,"width":12,"height":12},
18730 "college-24": {"x":54,"y":240,"width":24,"height":24},
18731 "college-18": {"x":78,"y":240,"width":18,"height":18},
18732 "college-12": {"x":96,"y":240,"width":12,"height":12},
18733 "library-24": {"x":108,"y":240,"width":24,"height":24},
18734 "library-18": {"x":132,"y":240,"width":18,"height":18},
18735 "library-12": {"x":150,"y":240,"width":12,"height":12},
18736 "post-24": {"x":162,"y":240,"width":24,"height":24},
18737 "post-18": {"x":186,"y":240,"width":18,"height":18},
18738 "post-12": {"x":204,"y":240,"width":12,"height":12},
18739 "fire-station-24": {"x":216,"y":240,"width":24,"height":24},
18740 "fire-station-18": {"x":240,"y":240,"width":18,"height":18},
18741 "fire-station-12": {"x":258,"y":240,"width":12,"height":12},
18742 "town-hall-24": {"x":0,"y":264,"width":24,"height":24},
18743 "town-hall-18": {"x":24,"y":264,"width":18,"height":18},
18744 "town-hall-12": {"x":42,"y":264,"width":12,"height":12},
18745 "police-24": {"x":54,"y":264,"width":24,"height":24},
18746 "police-18": {"x":78,"y":264,"width":18,"height":18},
18747 "police-12": {"x":96,"y":264,"width":12,"height":12},
18748 "prison-24": {"x":108,"y":264,"width":24,"height":24},
18749 "prison-18": {"x":132,"y":264,"width":18,"height":18},
18750 "prison-12": {"x":150,"y":264,"width":12,"height":12},
18751 "embassy-24": {"x":162,"y":264,"width":24,"height":24},
18752 "embassy-18": {"x":186,"y":264,"width":18,"height":18},
18753 "embassy-12": {"x":204,"y":264,"width":12,"height":12},
18754 "beer-24": {"x":216,"y":264,"width":24,"height":24},
18755 "beer-18": {"x":240,"y":264,"width":18,"height":18},
18756 "beer-12": {"x":258,"y":264,"width":12,"height":12},
18757 "restaurant-24": {"x":0,"y":288,"width":24,"height":24},
18758 "restaurant-18": {"x":24,"y":288,"width":18,"height":18},
18759 "restaurant-12": {"x":42,"y":288,"width":12,"height":12},
18760 "cafe-24": {"x":54,"y":288,"width":24,"height":24},
18761 "cafe-18": {"x":78,"y":288,"width":18,"height":18},
18762 "cafe-12": {"x":96,"y":288,"width":12,"height":12},
18763 "shop-24": {"x":108,"y":288,"width":24,"height":24},
18764 "shop-18": {"x":132,"y":288,"width":18,"height":18},
18765 "shop-12": {"x":150,"y":288,"width":12,"height":12},
18766 "fast-food-24": {"x":162,"y":288,"width":24,"height":24},
18767 "fast-food-18": {"x":186,"y":288,"width":18,"height":18},
18768 "fast-food-12": {"x":204,"y":288,"width":12,"height":12},
18769 "bar-24": {"x":216,"y":288,"width":24,"height":24},
18770 "bar-18": {"x":240,"y":288,"width":18,"height":18},
18771 "bar-12": {"x":258,"y":288,"width":12,"height":12},
18772 "bank-24": {"x":0,"y":312,"width":24,"height":24},
18773 "bank-18": {"x":24,"y":312,"width":18,"height":18},
18774 "bank-12": {"x":42,"y":312,"width":12,"height":12},
18775 "grocery-24": {"x":54,"y":312,"width":24,"height":24},
18776 "grocery-18": {"x":78,"y":312,"width":18,"height":18},
18777 "grocery-12": {"x":96,"y":312,"width":12,"height":12},
18778 "cinema-24": {"x":108,"y":312,"width":24,"height":24},
18779 "cinema-18": {"x":132,"y":312,"width":18,"height":18},
18780 "cinema-12": {"x":150,"y":312,"width":12,"height":12},
18781 "pharmacy-24": {"x":162,"y":312,"width":24,"height":24},
18782 "pharmacy-18": {"x":186,"y":312,"width":18,"height":18},
18783 "pharmacy-12": {"x":204,"y":312,"width":12,"height":12},
18784 "hospital-24": {"x":216,"y":312,"width":24,"height":24},
18785 "hospital-18": {"x":240,"y":312,"width":18,"height":18},
18786 "hospital-12": {"x":258,"y":312,"width":12,"height":12},
18787 "danger-24": {"x":0,"y":336,"width":24,"height":24},
18788 "danger-18": {"x":24,"y":336,"width":18,"height":18},
18789 "danger-12": {"x":42,"y":336,"width":12,"height":12},
18790 "industrial-24": {"x":54,"y":336,"width":24,"height":24},
18791 "industrial-18": {"x":78,"y":336,"width":18,"height":18},
18792 "industrial-12": {"x":96,"y":336,"width":12,"height":12},
18793 "warehouse-24": {"x":108,"y":336,"width":24,"height":24},
18794 "warehouse-18": {"x":132,"y":336,"width":18,"height":18},
18795 "warehouse-12": {"x":150,"y":336,"width":12,"height":12},
18796 "commercial-24": {"x":162,"y":336,"width":24,"height":24},
18797 "commercial-18": {"x":186,"y":336,"width":18,"height":18},
18798 "commercial-12": {"x":204,"y":336,"width":12,"height":12},
18799 "building-24": {"x":216,"y":336,"width":24,"height":24},
18800 "building-18": {"x":240,"y":336,"width":18,"height":18},
18801 "building-12": {"x":258,"y":336,"width":12,"height":12},
18802 "place-of-worship-24": {"x":0,"y":360,"width":24,"height":24},
18803 "place-of-worship-18": {"x":24,"y":360,"width":18,"height":18},
18804 "place-of-worship-12": {"x":42,"y":360,"width":12,"height":12},
18805 "alcohol-shop-24": {"x":54,"y":360,"width":24,"height":24},
18806 "alcohol-shop-18": {"x":78,"y":360,"width":18,"height":18},
18807 "alcohol-shop-12": {"x":96,"y":360,"width":12,"height":12},
18808 "logging-24": {"x":108,"y":360,"width":24,"height":24},
18809 "logging-18": {"x":132,"y":360,"width":18,"height":18},
18810 "logging-12": {"x":150,"y":360,"width":12,"height":12},
18811 "oil-well-24": {"x":162,"y":360,"width":24,"height":24},
18812 "oil-well-18": {"x":186,"y":360,"width":18,"height":18},
18813 "oil-well-12": {"x":204,"y":360,"width":12,"height":12},
18814 "slaughterhouse-24": {"x":216,"y":360,"width":24,"height":24},
18815 "slaughterhouse-18": {"x":240,"y":360,"width":18,"height":18},
18816 "slaughterhouse-12": {"x":258,"y":360,"width":12,"height":12},
18817 "dam-24": {"x":0,"y":384,"width":24,"height":24},
18818 "dam-18": {"x":24,"y":384,"width":18,"height":18},
18819 "dam-12": {"x":42,"y":384,"width":12,"height":12},
18820 "water-24": {"x":54,"y":384,"width":24,"height":24},
18821 "water-18": {"x":78,"y":384,"width":18,"height":18},
18822 "water-12": {"x":96,"y":384,"width":12,"height":12},
18823 "wetland-24": {"x":108,"y":384,"width":24,"height":24},
18824 "wetland-18": {"x":132,"y":384,"width":18,"height":18},
18825 "wetland-12": {"x":150,"y":384,"width":12,"height":12},
18826 "disability-24": {"x":162,"y":384,"width":24,"height":24},
18827 "disability-18": {"x":186,"y":384,"width":18,"height":18},
18828 "disability-12": {"x":204,"y":384,"width":12,"height":12},
18829 "telephone-24": {"x":216,"y":384,"width":24,"height":24},
18830 "telephone-18": {"x":240,"y":384,"width":18,"height":18},
18831 "telephone-12": {"x":258,"y":384,"width":12,"height":12},
18832 "emergency-telephone-24": {"x":0,"y":408,"width":24,"height":24},
18833 "emergency-telephone-18": {"x":24,"y":408,"width":18,"height":18},
18834 "emergency-telephone-12": {"x":42,"y":408,"width":12,"height":12},
18835 "toilets-24": {"x":54,"y":408,"width":24,"height":24},
18836 "toilets-18": {"x":78,"y":408,"width":18,"height":18},
18837 "toilets-12": {"x":96,"y":408,"width":12,"height":12},
18838 "waste-basket-24": {"x":108,"y":408,"width":24,"height":24},
18839 "waste-basket-18": {"x":132,"y":408,"width":18,"height":18},
18840 "waste-basket-12": {"x":150,"y":408,"width":12,"height":12},
18841 "music-24": {"x":162,"y":408,"width":24,"height":24},
18842 "music-18": {"x":186,"y":408,"width":18,"height":18},
18843 "music-12": {"x":204,"y":408,"width":12,"height":12},
18844 "land-use-24": {"x":216,"y":408,"width":24,"height":24},
18845 "land-use-18": {"x":240,"y":408,"width":18,"height":18},
18846 "land-use-12": {"x":258,"y":408,"width":12,"height":12},
18847 "city-24": {"x":0,"y":432,"width":24,"height":24},
18848 "city-18": {"x":24,"y":432,"width":18,"height":18},
18849 "city-12": {"x":42,"y":432,"width":12,"height":12},
18850 "town-24": {"x":54,"y":432,"width":24,"height":24},
18851 "town-18": {"x":78,"y":432,"width":18,"height":18},
18852 "town-12": {"x":96,"y":432,"width":12,"height":12},
18853 "village-24": {"x":108,"y":432,"width":24,"height":24},
18854 "village-18": {"x":132,"y":432,"width":18,"height":18},
18855 "village-12": {"x":150,"y":432,"width":12,"height":12},
18856 "farm-24": {"x":162,"y":432,"width":24,"height":24},
18857 "farm-18": {"x":186,"y":432,"width":18,"height":18},
18858 "farm-12": {"x":204,"y":432,"width":12,"height":12},
18859 "bakery-24": {"x":216,"y":432,"width":24,"height":24},
18860 "bakery-18": {"x":240,"y":432,"width":18,"height":18},
18861 "bakery-12": {"x":258,"y":432,"width":12,"height":12},
18862 "dog-park-24": {"x":0,"y":456,"width":24,"height":24},
18863 "dog-park-18": {"x":24,"y":456,"width":18,"height":18},
18864 "dog-park-12": {"x":42,"y":456,"width":12,"height":12},
18865 "lighthouse-24": {"x":54,"y":456,"width":24,"height":24},
18866 "lighthouse-18": {"x":78,"y":456,"width":18,"height":18},
18867 "lighthouse-12": {"x":96,"y":456,"width":12,"height":12},
18868 "clothing-store-24": {"x":108,"y":456,"width":24,"height":24},
18869 "clothing-store-18": {"x":132,"y":456,"width":18,"height":18},
18870 "clothing-store-12": {"x":150,"y":456,"width":12,"height":12},
18871 "polling-place-24": {"x":162,"y":456,"width":24,"height":24},
18872 "polling-place-18": {"x":186,"y":456,"width":18,"height":18},
18873 "polling-place-12": {"x":204,"y":456,"width":12,"height":12},
18874 "playground-24": {"x":216,"y":456,"width":24,"height":24},
18875 "playground-18": {"x":240,"y":456,"width":18,"height":18},
18876 "playground-12": {"x":258,"y":456,"width":12,"height":12},
18877 "entrance-24": {"x":0,"y":480,"width":24,"height":24},
18878 "entrance-18": {"x":24,"y":480,"width":18,"height":18},
18879 "entrance-12": {"x":42,"y":480,"width":12,"height":12},
18880 "heart-24": {"x":54,"y":480,"width":24,"height":24},
18881 "heart-18": {"x":78,"y":480,"width":18,"height":18},
18882 "heart-12": {"x":96,"y":480,"width":12,"height":12},
18883 "london-underground-24": {"x":108,"y":480,"width":24,"height":24},
18884 "london-underground-18": {"x":132,"y":480,"width":18,"height":18},
18885 "london-underground-12": {"x":150,"y":480,"width":12,"height":12},
18886 "minefield-24": {"x":162,"y":480,"width":24,"height":24},
18887 "minefield-18": {"x":186,"y":480,"width":18,"height":18},
18888 "minefield-12": {"x":204,"y":480,"width":12,"height":12},
18889 "rail-underground-24": {"x":216,"y":480,"width":24,"height":24},
18890 "rail-underground-18": {"x":240,"y":480,"width":18,"height":18},
18891 "rail-underground-12": {"x":258,"y":480,"width":12,"height":12},
18892 "rail-above-24": {"x":0,"y":504,"width":24,"height":24},
18893 "rail-above-18": {"x":24,"y":504,"width":18,"height":18},
18894 "rail-above-12": {"x":42,"y":504,"width":12,"height":12},
18895 "camera-24": {"x":54,"y":504,"width":24,"height":24},
18896 "camera-18": {"x":78,"y":504,"width":18,"height":18},
18897 "camera-12": {"x":96,"y":504,"width":12,"height":12},
18898 "laundry-24": {"x":108,"y":504,"width":24,"height":24},
18899 "laundry-18": {"x":132,"y":504,"width":18,"height":18},
18900 "laundry-12": {"x":150,"y":504,"width":12,"height":12},
18901 "car-24": {"x":162,"y":504,"width":24,"height":24},
18902 "car-18": {"x":186,"y":504,"width":18,"height":18},
18903 "car-12": {"x":204,"y":504,"width":12,"height":12},
18904 "suitcase-24": {"x":216,"y":504,"width":24,"height":24},
18905 "suitcase-18": {"x":240,"y":504,"width":18,"height":18},
18906 "suitcase-12": {"x":258,"y":504,"width":12,"height":12},
18907 "hairdresser-24": {"x":0,"y":528,"width":24,"height":24},
18908 "hairdresser-18": {"x":24,"y":528,"width":18,"height":18},
18909 "hairdresser-12": {"x":42,"y":528,"width":12,"height":12},
18910 "chemist-24": {"x":54,"y":528,"width":24,"height":24},
18911 "chemist-18": {"x":78,"y":528,"width":18,"height":18},
18912 "chemist-12": {"x":96,"y":528,"width":12,"height":12},
18913 "mobilephone-24": {"x":108,"y":528,"width":24,"height":24},
18914 "mobilephone-18": {"x":132,"y":528,"width":18,"height":18},
18915 "mobilephone-12": {"x":150,"y":528,"width":12,"height":12},
18916 "scooter-24": {"x":162,"y":528,"width":24,"height":24},
18917 "scooter-18": {"x":186,"y":528,"width":18,"height":18},
18918 "scooter-12": {"x":204,"y":528,"width":12,"height":12},
18919 "gift-24": {"x":216,"y":528,"width":24,"height":24},
18920 "gift-18": {"x":240,"y":528,"width":18,"height":18},
18921 "gift-12": {"x":258,"y":528,"width":12,"height":12},
18922 "ice-cream-24": {"x":0,"y":552,"width":24,"height":24},
18923 "ice-cream-18": {"x":24,"y":552,"width":18,"height":18},
18924 "ice-cream-12": {"x":42,"y":552,"width":12,"height":12}
18927 var amenity = {"fuel":{"76":{"count":314},"Neste":{"count":189},"BP":{"count":2511},"Shell":{"count":8380},"Agip":{"count":2651},"Migrol":{"count":65},"Avia":{"count":897},"Texaco":{"count":680},"Total":{"count":2607},"Statoil":{"count":596},"Esso":{"count":3652},"Jet":{"count":441},"Avanti":{"count":90},"Sainsbury's":{"count":58},"OMV":{"count":701},"Aral":{"count":1339},"Tesco":{"count":197},"JET":{"count":180},"Morrisons":{"count":111},"United":{"count":91},"Canadian Tire":{"count":66},"Mobil":{"count":613},"Caltex":{"count":1001},"Sunoco":{"count":355},"Q8":{"count":1161},"ABC":{"count":79},"ARAL":{"count":375},"CEPSA":{"count":1018},"BFT":{"count":89},"Petron":{"count":878},"Intermarché":{"count":434},"Total Access":{"count":51},"Super U":{"count":124},"Auchan":{"count":53},"Elf":{"count":129},"Carrefour":{"count":205},"Station Service E. Leclerc":{"count":530},"Shell Express":{"count":131},"Hess":{"count":127},"Flying V":{"count":129},"bft":{"count":168},"Gulf":{"count":199},"PTT":{"count":191},"St1":{"count":100},"Teboil":{"count":115},"HEM":{"count":212},"GALP":{"count":626},"OK":{"count":163},"ÖMV":{"count":101},"Tinq":{"count":215},"OKQ8":{"count":186},"Repsol":{"count":424},"Westfalen":{"count":96},"Esso Express":{"count":98},"Raiffeisenbank":{"count":117},"Tamoil":{"count":866},"Engen":{"count":241},"Sasol":{"count":59},"Topaz":{"count":78},"LPG":{"count":174},"Coop":{"count":62},"Orlen":{"count":598},"Oilibya":{"count":68},"Tango":{"count":122},"Star":{"count":319},"Петрол":{"count":84},"Cepsa":{"count":96},"OIL!":{"count":63},"Ultramar":{"count":125},"Irving":{"count":87},"Lukoil":{"count":701},"Petro-Canada":{"count":489},"7-Eleven":{"count":488},"Agrola":{"count":69},"Husky":{"count":126},"Slovnaft":{"count":219},"Sheetz":{"count":134},"Mol":{"count":61},"Petronas":{"count":159},"Газпромнефть":{"count":748},"Лукойл":{"count":1477},"Elan":{"count":112},"Роснефть":{"count":638},"Turmöl":{"count":57},"Neste A24":{"count":55},"Marathon":{"count":189},"Valero":{"count":366},"Eni":{"count":236},"Chevron":{"count":954},"ТНК":{"count":520},"REPSOL":{"count":1603},"MOL":{"count":228},"Bliska":{"count":150},"Api":{"count":302},"Arco":{"count":179},"Pemex":{"count":423},"Exxon":{"count":506},"Coles Express":{"count":115},"Petrom":{"count":259},"PETRONOR":{"count":207},"Rompetrol":{"count":174},"Lotos":{"count":178},"ОМВ":{"count":60},"BR":{"count":129},"Copec":{"count":505},"Petrobras":{"count":270},"Liberty":{"count":55},"IP":{"count":871},"Erg":{"count":596},"Eneos":{"count":97},"Citgo":{"count":279},"Metano":{"count":208},"Сургутнефтегаз":{"count":61},"EKO":{"count":59},"Eko":{"count":58},"Indipend.":{"count":172},"IES":{"count":63},"TotalErg":{"count":89},"Cenex":{"count":115},"ПТК":{"count":82},"HP":{"count":79},"Phillips 66":{"count":216},"CARREFOUR":{"count":74},"ERG":{"count":76},"Speedway":{"count":148},"Benzina":{"count":96},"Татнефть":{"count":264},"Terpel":{"count":259},"WOG":{"count":189},"Seaoil":{"count":54},"АЗС":{"count":1077},"Kwik Trip":{"count":108},"Wawa":{"count":89},"Pertamina":{"count":186},"COSMO":{"count":64},"Z":{"count":76},"Indian Oil":{"count":183},"АГЗС":{"count":494},"INA":{"count":121},"JOMO":{"count":62},"Holiday":{"count":97},"YPF":{"count":70},"IDEMITSU":{"count":87},"ENEOS":{"count":736},"Bharat Petroleum":{"count":64},"CAMPSA":{"count":615},"Casey's General Store":{"count":190},"Башнефть":{"count":60},"Kangaroo":{"count":60},"コスモ石油 (COSMO)":{"count":136},"MEROIL":{"count":77},"1-2-3":{"count":71},"出光":{"count":228,"tags":{"name:en":"IDEMITSU"}},"НК Альянс":{"count":88},"Sinclair":{"count":100},"Conoco":{"count":189},"SPBU":{"count":54},"Макпетрол":{"count":109},"Circle K":{"count":166},"Posto Ipiranga":{"count":70},"Posto Shell":{"count":54},"Phoenix":{"count":144},"Ipiranga":{"count":119},"OKKO":{"count":85},"ОККО":{"count":119},"บางจาก":{"count":60},"QuikTrip":{"count":105},"Stewart's":{"count":63},"Posto BR":{"count":68},"ป ต ท":{"count":152},"ปตท":{"count":88},"ANP":{"count":80},"Kum & Go":{"count":80},"Petrolimex":{"count":55},"Sokimex":{"count":66},"Tela":{"count":154},"Posto":{"count":71},"H-E-B":{"count":182},"Укрнафта":{"count":58},"Татнефтепродукт":{"count":54},"Afriquia":{"count":88},"Murphy USA":{"count":67},"昭和シェル (Showa-shell)":{"count":94},"エネオス":{"count":53},"CNG":{"count":94}},"pub":{"Kings Arms":{"count":67},"The Ship":{"count":89},"The White Horse":{"count":204},"The White Hart":{"count":226},"Royal Oak":{"count":150},"The Red Lion":{"count":233},"The Kings Arms":{"count":58},"The Star":{"count":73},"The Anchor":{"count":64},"The Cross Keys":{"count":55},"The Wheatsheaf":{"count":117},"The Crown Inn":{"count":67},"The Kings Head":{"count":53},"The Castle":{"count":62},"The Railway":{"count":102},"The White Lion":{"count":118},"The Bell":{"count":121},"The Bull":{"count":68},"The Plough":{"count":179},"The George":{"count":110},"The Royal Oak":{"count":209},"The Fox":{"count":74},"Prince of Wales":{"count":77},"The Rising Sun":{"count":71},"The Prince of Wales":{"count":51},"The Crown":{"count":244},"The Chequers":{"count":66},"The Swan":{"count":152},"Rose and Crown":{"count":79},"The Victoria":{"count":67},"New Inn":{"count":90},"Royal Hotel":{"count":57},"Red Lion":{"count":207},"Cross Keys":{"count":61},"The Greyhound":{"count":96},"The Black Horse":{"count":94},"The New Inn":{"count":105},"Kings Head":{"count":59},"The Albion":{"count":51},"The Angel":{"count":52},"The Queens Head":{"count":52},"The Ship Inn":{"count":83},"Rose & Crown":{"count":51},"Queens Head":{"count":52},"Irish Pub":{"count":76}},"fast_food":{"Quick":{"count":484},"McDonald's":{"count":12376,"tags":{"cuisine":"burger"}},"Subway":{"count":5576,"tags":{"cuisine":"sandwich"}},"Burger King":{"count":3734,"tags":{"cuisine":"burger"}},"Ali Baba":{"count":61},"Hungry Jacks":{"count":173,"tags":{"cuisine":"burger"}},"Red Rooster":{"count":148},"KFC":{"count":3198,"tags":{"cuisine":"chicken"}},"Domino's Pizza":{"count":985,"tags":{"cuisine":"pizza"}},"Chowking":{"count":142},"Jollibee":{"count":396},"Hesburger":{"count":102},"肯德基":{"count":86},"Wendy's":{"count":1621,"tags":{"cuisine":"burger"}},"Tim Hortons":{"count":323},"Steers":{"count":151},"Hardee's":{"count":268,"tags":{"cuisine":"burger"}},"Arby's":{"count":782},"A&W":{"count":283},"Dairy Queen":{"count":791},"Hallo Pizza":{"count":76},"Fish & Chips":{"count":93},"Harvey's":{"count":90},"麥當勞":{"count":65},"Pizza Pizza":{"count":215},"Kotipizza":{"count":74},"Jack in the Box":{"count":546,"tags":{"cuisine":"burger"}},"Istanbul":{"count":56},"Kochlöffel":{"count":68},"Döner":{"count":228},"Telepizza":{"count":201},"Sibylla":{"count":61},"Carl's Jr.":{"count":298,"tags":{"cuisine":"burger"}},"Quiznos":{"count":266,"tags":{"cuisine":"sandwich"}},"Wimpy":{"count":141},"Sonic":{"count":566,"tags":{"cuisine":"burger"}},"Taco Bell":{"count":1423,"tags":{"cuisine":"mexican"}},"Pizza Nova":{"count":63},"Papa John's":{"count":304,"tags":{"cuisine":"pizza"}},"Nordsee":{"count":159},"Mr. Sub":{"count":103},"Макдоналдс":{"count":324,"tags":{"name:en":"McDonald's"}},"Asia Imbiss":{"count":111},"Chipotle":{"count":290,"tags":{"cuisine":"mexican"}},"マクドナルド":{"count":692,"tags":{"name:en":"McDonald's","cuisine":"burger"}},"In-N-Out Burger":{"count":65},"Jimmy John's":{"count":141},"Jamba Juice":{"count":68},"Робин Сдобин":{"count":82},"Baskin Robbins":{"count":74},"ケンタッキーフライドチキン":{"count":164,"tags":{"name:en":"KFC","cuisine":"chicken"}},"吉野家":{"count":191},"Taco Time":{"count":88},"松屋":{"count":281,"tags":{"name:en":"Matsuya"}},"Little Caesars":{"count":81},"El Pollo Loco":{"count":63},"Del Taco":{"count":141},"White Castle":{"count":80},"Boston Market":{"count":66},"Chick-fil-A":{"count":257,"tags":{"cuisine":"chicken"}},"Panda Express":{"count":238,"tags":{"cuisine":"chinese"}},"Whataburger":{"count":364},"Taco John's":{"count":78},"Теремок":{"count":68},"Culver's":{"count":425},"Five Guys":{"count":141},"Church's Chicken":{"count":95},"Popeye's":{"count":167,"tags":{"cuisine":"chicken"}},"Long John Silver's":{"count":93},"Pollo Campero":{"count":62},"Zaxby's":{"count":51},"すき家":{"count":276,"tags":{"name:en":"SUKIYA"}},"モスバーガー":{"count":257,"tags":{"name:en":"MOS BURGER"}},"Русский Аппетит":{"count":69},"なか卯":{"count":63}},"restaurant":{"Pizza Hut":{"count":1180,"tags":{"cuisine":"pizza"}},"Little Chef":{"count":64},"Adler":{"count":158},"Zur Krone":{"count":90},"Deutsches Haus":{"count":90},"Krone":{"count":171},"Akropolis":{"count":152},"Schützenhaus":{"count":124},"Kreuz":{"count":74},"Waldschänke":{"count":55},"La Piazza":{"count":69},"Lamm":{"count":66},"Zur Sonne":{"count":73},"Zur Linde":{"count":204},"Poseidon":{"count":110},"Shanghai":{"count":82},"Red Lobster":{"count":235},"Zum Löwen":{"count":84},"Swiss Chalet":{"count":107},"Olympia":{"count":74},"Wagamama":{"count":64},"Frankie & Benny's":{"count":66},"Hooters":{"count":103},"Sternen":{"count":78},"Hirschen":{"count":79},"Denny's":{"count":450},"Athen":{"count":68},"Sonne":{"count":126},"Hirsch":{"count":79},"Ratskeller":{"count":150},"La Cantina":{"count":56},"Gasthaus Krone":{"count":56},"El Greco":{"count":86},"Gasthof zur Post":{"count":79},"Nando's":{"count":246},"Löwen":{"count":112},"La Pataterie":{"count":51},"Bella Napoli":{"count":53},"Pizza Express":{"count":262},"Mandarin":{"count":65},"Hong Kong":{"count":83},"Zizzi":{"count":68},"Cracker Barrel":{"count":183},"Rhodos":{"count":81},"Lindenhof":{"count":79},"Milano":{"count":54},"Dolce Vita":{"count":77},"Kirchenwirt":{"count":81},"Kantine":{"count":52},"Ochsen":{"count":95},"Spur":{"count":62},"Mykonos":{"count":59},"Lotus":{"count":66},"Applebee's":{"count":531},"Flunch":{"count":72},"Zur Post":{"count":116},"China Town":{"count":76},"La Dolce Vita":{"count":73},"Waffle House":{"count":207},"Delphi":{"count":88},"Linde":{"count":103},"Outback Steakhouse":{"count":218},"Dionysos":{"count":69},"Kelsey's":{"count":57},"Boston Pizza":{"count":165},"Bella Italia":{"count":132},"Sizzler":{"count":53},"Grüner Baum":{"count":116},"Taj Mahal":{"count":104},"Rössli":{"count":68},"Wimpy":{"count":51},"Traube":{"count":65},"Adria":{"count":52},"Red Robin":{"count":185},"Roma":{"count":61},"San Marco":{"count":67},"Hellas":{"count":55},"La Perla":{"count":67},"Vips":{"count":53},"Panera Bread":{"count":218},"Da Vinci":{"count":54},"Hippopotamus":{"count":96},"Prezzo":{"count":75},"Courtepaille":{"count":106},"Hard Rock Cafe":{"count":70},"Panorama":{"count":61},"デニーズ":{"count":82},"Sportheim":{"count":65},"餃子の王将":{"count":57},"Bären":{"count":60},"Alte Post":{"count":60},"Pizzeria Roma":{"count":51},"China Garden":{"count":66},"Vapiano":{"count":82},"Mamma Mia":{"count":64},"Schwarzer Adler":{"count":57},"IHOP":{"count":317},"Chili's":{"count":328},"Asia":{"count":51},"Olive Garden":{"count":279},"TGI Friday's":{"count":159},"Friendly's":{"count":78},"Buffalo Grill":{"count":202},"Texas Roadhouse":{"count":110},"ガスト":{"count":230,"tags":{"name:en":"Gusto"}},"Sakura":{"count":75},"Mensa":{"count":99},"The Keg":{"count":53},"サイゼリヤ":{"count":93},"La Strada":{"count":52},"Village Inn":{"count":92},"Buffalo Wild Wings":{"count":176},"Peking":{"count":59},"Boston Market":{"count":61},"Round Table Pizza":{"count":53},"Jimmy John's":{"count":69},"California Pizza Kitchen":{"count":61},"Якитория":{"count":77},"Golden Corral":{"count":101},"Perkins":{"count":105},"Ruby Tuesday":{"count":162},"Shari's":{"count":65},"Bob Evans":{"count":129},"바다횟집 (Bada Fish Restaurant)":{"count":55},"Mang Inasal":{"count":84},"Евразия":{"count":102},"ジョナサン":{"count":59},"Longhorn Steakhouse":{"count":66}},"bank":{"Chase":{"count":721},"Commonwealth Bank":{"count":232},"Citibank":{"count":277},"HSBC":{"count":1102},"Barclays":{"count":965},"Westpac":{"count":208},"NAB":{"count":131},"ANZ":{"count":218},"Lloyds Bank":{"count":547},"Landbank":{"count":81},"Sparkasse":{"count":4555},"UCPB":{"count":92},"PNB":{"count":244},"Metrobank":{"count":269},"BDO":{"count":290},"Volksbank":{"count":2591},"BPI":{"count":415},"Postbank":{"count":443},"NatWest":{"count":628},"Raiffeisenbank":{"count":2119},"Yorkshire Bank":{"count":63},"ABSA":{"count":95},"Standard Bank":{"count":109},"FNB":{"count":97},"Deutsche Bank":{"count":855},"SEB":{"count":133},"Commerzbank":{"count":806},"Targobank":{"count":166},"ABN AMRO":{"count":130},"Handelsbanken":{"count":184},"Swedbank":{"count":223},"Kreissparkasse":{"count":600},"UniCredit Bank":{"count":408},"Monte dei Paschi di Siena":{"count":132},"Caja Rural":{"count":99},"Dresdner Bank":{"count":66},"Sparda-Bank":{"count":320},"VÚB":{"count":107},"Slovenská sporiteľňa":{"count":134},"Bank of Montreal":{"count":118},"KBC":{"count":203},"Royal Bank of Scotland":{"count":111},"TSB":{"count":80},"US Bank":{"count":256},"HypoVereinsbank":{"count":561},"Bank Austria":{"count":176},"ING":{"count":496},"Erste Bank":{"count":180},"CIBC":{"count":326},"Scotiabank":{"count":413},"Caisse d'Épargne":{"count":882},"Santander":{"count":1323},"Bank of Scotland":{"count":89},"TD Canada Trust":{"count":450},"BMO":{"count":169},"Danske Bank":{"count":131},"OTP":{"count":192},"Crédit Agricole":{"count":1239},"LCL":{"count":553},"VR-Bank":{"count":430},"ČSOB":{"count":160},"Česká spořitelna":{"count":212},"BNP":{"count":112},"Royal Bank":{"count":65},"Nationwide":{"count":209},"Halifax":{"count":225},"BAWAG PSK":{"count":102},"National Bank":{"count":84},"Nedbank":{"count":80},"First National Bank":{"count":85},"Nordea":{"count":319},"Rabobank":{"count":609},"Sparkasse KölnBonn":{"count":69},"Tatra banka":{"count":67},"Berliner Sparkasse":{"count":62},"Berliner Volksbank":{"count":77},"Wells Fargo":{"count":874},"Credit Suisse":{"count":71},"Société Générale":{"count":634},"Osuuspankki":{"count":75},"Sparkasse Aachen":{"count":56},"Hamburger Sparkasse":{"count":156},"Cassa di Risparmio del Veneto":{"count":68},"BNP Paribas":{"count":617},"Banque Populaire":{"count":433},"BNP Paribas Fortis":{"count":209},"Banco Popular":{"count":291},"Bancaja":{"count":55},"Banesto":{"count":208},"La Caixa":{"count":583},"Santander Consumer Bank":{"count":88},"BRD":{"count":191},"BCR":{"count":143},"Banca Transilvania":{"count":141},"BW-Bank":{"count":97},"Komerční banka":{"count":132},"Banco Pastor":{"count":64},"Stadtsparkasse":{"count":86},"Ulster Bank":{"count":86},"Sberbank":{"count":58},"CIC":{"count":427},"Bancpost":{"count":56},"Caja Madrid":{"count":115},"Maybank":{"count":94},"中国银行":{"count":85},"Unicredit Banca":{"count":243},"Crédit Mutuel":{"count":690},"BBVA":{"count":647},"Intesa San Paolo":{"count":69},"TD Bank":{"count":206},"Belfius":{"count":231},"Bank of America":{"count":924},"RBC":{"count":230},"Alpha Bank":{"count":123},"Сбербанк":{"count":4794},"Россельхозбанк":{"count":201},"Crédit du Nord":{"count":96},"BancoEstado":{"count":80},"Millennium Bank":{"count":414},"State Bank of India":{"count":151},"Беларусбанк":{"count":242},"ING Bank Śląski":{"count":67},"Caixa Geral de Depósitos":{"count":129},"Kreissparkasse Köln":{"count":65},"Banco BCI":{"count":51},"Banco de Chile":{"count":98},"ВТБ24":{"count":326},"UBS":{"count":134},"PKO BP":{"count":265},"Chinabank":{"count":55},"PSBank":{"count":59},"Union Bank":{"count":124},"China Bank":{"count":66},"RCBC":{"count":122},"Unicaja":{"count":83},"BBK":{"count":79},"Ibercaja":{"count":69},"RBS":{"count":143},"Commercial Bank of Ceylon PLC":{"count":79},"Bank of Ireland":{"count":109},"BNL":{"count":87},"Banco Santander":{"count":138},"Banco Itaú":{"count":111},"AIB":{"count":72},"BZ WBK":{"count":77},"Banco do Brasil":{"count":557},"Caixa Econômica Federal":{"count":184},"Fifth Third Bank":{"count":84},"Banca Popolare di Vicenza":{"count":81},"Wachovia":{"count":58},"OLB":{"count":53},"みずほ銀行":{"count":78},"BES":{"count":72},"ICICI Bank":{"count":91},"HDFC Bank":{"count":91},"La Banque Postale":{"count":67},"Pekao SA":{"count":56},"Oberbank":{"count":90},"Bradesco":{"count":295},"Oldenburgische Landesbank":{"count":56},"Bendigo Bank":{"count":93},"Argenta":{"count":86},"AXA":{"count":68},"Axis Bank":{"count":61},"Banco Nación":{"count":67},"GE Money Bank":{"count":72},"Альфа-Банк":{"count":185},"Белагропромбанк":{"count":70},"Caja Círculo":{"count":65},"Banco Galicia":{"count":51},"Eurobank":{"count":97},"Banca Intesa":{"count":62},"Canara Bank":{"count":92},"Cajamar":{"count":77},"Banamex":{"count":149},"Crédit Mutuel de Bretagne":{"count":335},"Davivienda":{"count":83},"Bank Spółdzielczy":{"count":159},"Credit Agricole":{"count":157},"Bankinter":{"count":59},"Banque Nationale":{"count":63},"Bank of the West":{"count":96},"Key Bank":{"count":155},"Western Union":{"count":88},"Citizens Bank":{"count":115},"ПриватБанк":{"count":513},"Security Bank":{"count":78},"Millenium":{"count":60},"Bankia":{"count":149},"三菱東京UFJ銀行":{"count":159},"Caixa":{"count":117},"Banco de Costa Rica":{"count":63},"SunTrust Bank":{"count":73},"Itaú":{"count":338},"PBZ":{"count":52},"中国工商银行":{"count":51},"Bancolombia":{"count":89},"Райффайзен Банк Аваль":{"count":64},"Bancomer":{"count":115},"Banorte":{"count":80},"Alior Bank":{"count":81},"BOC":{"count":51},"Банк Москвы":{"count":118},"ВТБ":{"count":59},"Getin Bank":{"count":55},"Caja Duero":{"count":57},"Regions Bank":{"count":62},"Росбанк":{"count":177},"Banco Estado":{"count":72},"BCI":{"count":68},"SunTrust":{"count":68},"PNC Bank":{"count":254},"신한은행":{"count":217,"tags":{"name:en":"Sinhan Bank"}},"우리은행":{"count":291,"tags":{"name:en":"Uri Bank"}},"국민은행":{"count":165,"tags":{"name:en":"Gungmin Bank"}},"중소기업은행":{"count":52,"tags":{"name:en":"Industrial Bank of Korea"}},"광주은행":{"count":51,"tags":{"name:en":"Gwangju Bank"}},"Газпромбанк":{"count":100},"M&T Bank":{"count":92},"Caja de Burgos":{"count":51},"Santander Totta":{"count":69},"УкрСиббанк":{"count":192},"Ощадбанк":{"count":364},"Уралсиб":{"count":85},"りそな銀行":{"count":225,"tags":{"name:en":"Mizuho Bank"}},"Ecobank":{"count":66},"Cajero Automatico Bancared":{"count":145},"Промсвязьбанк":{"count":93},"三井住友銀行":{"count":129},"Banco Provincia":{"count":67},"BB&T":{"count":147},"Возрождение":{"count":59},"Capital One":{"count":59},"横浜銀行":{"count":51},"Bank Mandiri":{"count":62},"Banco de la Nación":{"count":92},"Banco G&T Continental":{"count":62},"Peoples Bank":{"count":60},"工商银行":{"count":51},"Совкомбанк":{"count":55},"Provincial":{"count":56},"Banco de Desarrollo Banrural":{"count":73},"Banco Bradesco":{"count":65},"Bicentenario":{"count":182},"ლიბერთი ბანკი":{"count":54,"tags":{"name:en":"Liberty Bank"}},"Banesco":{"count":108},"Mercantil":{"count":75},"Bank BRI":{"count":53},"Del Tesoro":{"count":91},"하나은행":{"count":77},"CityCommerce Bank":{"count":71},"De Venezuela":{"count":117}},"car_rental":{"Europcar":{"count":291},"Budget":{"count":92},"Sixt":{"count":161},"Avis":{"count":282},"Hertz":{"count":293},"Enterprise":{"count":199},"stadtmobil CarSharing-Station":{"count":148}},"pharmacy":{"Rowlands Pharmacy":{"count":71},"Boots":{"count":840},"Marien-Apotheke":{"count":314},"Mercury Drug":{"count":426},"Löwen-Apotheke":{"count":356},"Superdrug":{"count":117},"Sonnen-Apotheke":{"count":311},"Rathaus-Apotheke":{"count":132},"Engel-Apotheke":{"count":123},"Hirsch-Apotheke":{"count":83},"Stern-Apotheke":{"count":67},"Lloyds Pharmacy":{"count":295},"Rosen-Apotheke":{"count":208},"Stadt-Apotheke":{"count":302},"Markt-Apotheke":{"count":164},"Аптека":{"count":1989},"Pharmasave":{"count":64},"Brunnen-Apotheke":{"count":53},"Shoppers Drug Mart":{"count":430},"Apotheke am Markt":{"count":60},"Alte Apotheke":{"count":88},"Neue Apotheke":{"count":109},"Gintarinė vaistinė":{"count":101},"Rats-Apotheke":{"count":84},"Adler Apotheke":{"count":313},"Pharmacie Centrale":{"count":64},"Walgreens":{"count":1619},"Rite Aid":{"count":745},"Apotheke":{"count":165},"Linden-Apotheke":{"count":211},"Bahnhof-Apotheke":{"count":66},"Burg-Apotheke":{"count":55},"Jean Coutu":{"count":62},"Pharmaprix":{"count":60},"Farmacias Ahumada":{"count":104},"Farmacia Comunale":{"count":113},"Farmacias Cruz Verde":{"count":86},"Cruz Verde":{"count":99},"Hubertus Apotheke":{"count":52},"CVS":{"count":1560},"Farmacias SalcoBrand":{"count":133},"Фармация":{"count":120},"Bären-Apotheke":{"count":74},"Clicks":{"count":113},"セイジョー":{"count":53},"マツモトキヨシ":{"count":115},"Dr. Max":{"count":51},"Вита":{"count":106},"Радуга":{"count":70},"サンドラッグ":{"count":61},"Apteka":{"count":366},"Первая помощь":{"count":74},"Ригла":{"count":113},"Имплозия":{"count":63},"Kinney Drugs":{"count":68},"Классика":{"count":67},"Ljekarna":{"count":53},"SalcoBrand":{"count":88},"Аптека 36,6":{"count":224},"Фармакор":{"count":75},"スギ薬局":{"count":84},"Аптечный пункт":{"count":148},"Невис":{"count":60},"トモズ (Tomod's)":{"count":83},"Eurovaistinė":{"count":65},"Farmacity":{"count":68},"аптека":{"count":96},"The Generics Pharmacy":{"count":95},"Farmatodo":{"count":123},"Duane Reade":{"count":61},"H-E-B":{"count":262},"Фармленд":{"count":82},"ドラッグてらしま (Drug Terashima)":{"count":96},"Арніка":{"count":125},"ავერსი (Aversi)":{"count":62},"Farmahorro":{"count":58}},"cafe":{"Starbucks":{"count":4238,"tags":{"cuisine":"coffee_shop"}},"Cafeteria":{"count":115},"Costa":{"count":618},"Caffè Nero":{"count":169},"Кафе":{"count":226},"Café Central":{"count":61},"Second Cup":{"count":193},"Dunkin Donuts":{"count":428,"tags":{"cuisine":"donut"}},"Espresso House":{"count":53},"Segafredo":{"count":69},"Coffee Time":{"count":94},"Cafe Coffee Day":{"count":120},"Eiscafe Venezia":{"count":180},"スターバックス":{"count":251,"tags":{"name:en":"Starbucks"}},"Шоколадница":{"count":145},"Pret A Manger":{"count":119},"Столовая":{"count":391},"Jamba Juice":{"count":53},"ドトール":{"count":164,"tags":{"name:en":"DOUTOR"}},"Tchibo":{"count":100},"Кофе Хауз":{"count":104},"Caribou Coffee":{"count":100},"Уют":{"count":51},"Шашлычная":{"count":58},"คาเฟ่ อเมซอน":{"count":62},"Traveler's Coffee":{"count":60},"カフェ・ド・クリエ":{"count":67,"tags":{"name:en":"Cafe de CRIE"}},"Cafe Amazon":{"count":65}}};
18928 var shop = {"supermarket":{"Budgens":{"count":88},"Morrisons":{"count":411},"Interspar":{"count":142},"Merkur":{"count":107},"Sainsbury's":{"count":547},"Lidl":{"count":7130},"Edeka":{"count":2293},"Coles":{"count":400},"Iceland":{"count":315},"Coop":{"count":2100},"Tesco":{"count":1297},"Woolworths":{"count":541},"Zielpunkt":{"count":239},"Nahkauf":{"count":170},"Billa":{"count":1432},"Kaufland":{"count":1004},"Plus":{"count":120},"ALDI":{"count":5172},"Checkers":{"count":128},"Tesco Metro":{"count":137},"NP":{"count":153},"Penny":{"count":1759},"Norma":{"count":1068},"Asda":{"count":225},"Netto":{"count":4379},"Rewe":{"count":2645},"Aldi Süd":{"count":594},"Real":{"count":246},"Tesco Express":{"count":406},"King Soopers":{"count":72},"Kiwi":{"count":167},"Pick n Pay":{"count":241},"ICA":{"count":192},"Tengelmann":{"count":188},"Carrefour":{"count":1640},"Waitrose":{"count":258},"Spar":{"count":2386},"Hofer":{"count":442},"M-Preis":{"count":76},"tegut":{"count":210},"Sainsbury's Local":{"count":118},"E-Center":{"count":66},"Aldi Nord":{"count":210},"nahkauf":{"count":84},"Meijer":{"count":76},"Safeway":{"count":410},"Costco":{"count":152},"Albert":{"count":185},"Jumbo":{"count":194},"Shoprite":{"count":244},"MPreis":{"count":54},"Penny Market":{"count":429},"Tesco Extra":{"count":123},"Albert Heijn":{"count":476},"IGA":{"count":363},"Super U":{"count":488},"Metro":{"count":260},"Neukauf":{"count":77},"Migros":{"count":459},"Marktkauf":{"count":121},"Delikatesy Centrum":{"count":59},"C1000":{"count":307},"Hoogvliet":{"count":53},"Food Basics":{"count":75},"Casino":{"count":264},"Penny Markt":{"count":466},"Giant":{"count":191},"COOP Jednota":{"count":73},"Rema 1000":{"count":368},"Kaufpark":{"count":96},"ALDI SÜD":{"count":113},"Simply Market":{"count":330},"Konzum":{"count":230},"Carrefour Express":{"count":353},"Eurospar":{"count":270},"Mercator":{"count":125},"Famila":{"count":130},"Hemköp":{"count":82},"real,-":{"count":81},"Markant":{"count":88},"Volg":{"count":135},"Leader Price":{"count":267},"Treff 3000":{"count":94},"SuperBrugsen":{"count":67},"Kaiser's":{"count":256},"K+K":{"count":106},"Unimarkt":{"count":86},"Carrefour City":{"count":126},"Sobeys":{"count":122},"S-Market":{"count":109},"Combi":{"count":55},"Denner":{"count":276},"Konsum":{"count":133},"Franprix":{"count":312},"Monoprix":{"count":198},"Diska":{"count":69},"PENNY":{"count":79},"Dia":{"count":835},"Giant Eagle":{"count":85},"NORMA":{"count":115},"AD Delhaize":{"count":63},"Auchan":{"count":152},"Mercadona":{"count":769},"Consum":{"count":130},"Carrefour Market":{"count":80},"Whole Foods":{"count":210,"tags":{"shop":"supermarket"}},"Pam":{"count":56},"sky":{"count":105},"Despar":{"count":146},"Eroski":{"count":208},"Costcutter":{"count":63},"Maxi":{"count":108},"Colruyt":{"count":180},"The Co-operative":{"count":64},"Intermarché":{"count":1210},"Delhaize":{"count":207},"CBA":{"count":176},"Shopi":{"count":53},"Walmart":{"count":644},"Kroger":{"count":317},"Albertsons":{"count":242},"Trader Joe's":{"count":235},"Feneberg":{"count":58},"denn's Biomarkt":{"count":52},"dm":{"count":114},"Kvickly":{"count":55},"Makro":{"count":140},"Dico":{"count":53},"Nah & Frisch":{"count":73},"Champion":{"count":59},"ICA Supermarket":{"count":51},"Fakta":{"count":235},"Магнит":{"count":1760},"Caprabo":{"count":103},"Famiglia Cooperativa":{"count":64},"Народная 7Я семьЯ":{"count":154},"Esselunga":{"count":85},"Maxima":{"count":102},"Petit Casino":{"count":111},"Wasgau":{"count":60},"Pingo Doce":{"count":253},"Match":{"count":140},"Profi":{"count":60},"Lider":{"count":65},"Unimarc":{"count":177},"The Co-operative Food":{"count":190},"Santa Isabel":{"count":128},"Седьмой континент":{"count":79},"HIT":{"count":59},"Rimi":{"count":106},"Conad":{"count":304},"Фуршет":{"count":76},"Willys":{"count":56},"Farmfoods":{"count":64},"U Express":{"count":51},"Фора":{"count":52},"Dunnes Stores":{"count":73},"Сільпо":{"count":125},"マルエツ":{"count":59},"Piggly Wiggly":{"count":57},"Crai":{"count":54},"El Árbol":{"count":73},"Centre Commercial E. Leclerc":{"count":549},"Foodland":{"count":100},"Super Brugsen":{"count":67},"Дикси":{"count":683},"Пятёрочка":{"count":1344},"Publix":{"count":339},"Føtex":{"count":66},"coop":{"count":73},"Fressnapf":{"count":69},"Coop Konsum":{"count":79},"Carrefour Contact":{"count":83},"No Frills":{"count":105},"Plodine":{"count":52},"ADEG":{"count":68},"Minipreço":{"count":111},"Biedronka":{"count":1335},"Eurospin":{"count":155},"Семья":{"count":62},"Gadis":{"count":53},"Евроопт":{"count":68},"Centra":{"count":51},"Квартал":{"count":82},"New World":{"count":69},"Countdown":{"count":95},"Reliance Fresh":{"count":61},"Stokrotka":{"count":98},"Coop Jednota":{"count":74},"Fred Meyer":{"count":64},"Irma":{"count":58},"Continente":{"count":75},"Price Chopper":{"count":99},"Game":{"count":52},"Soriana":{"count":93},"Alimerka":{"count":64},"Piotr i Paweł":{"count":53},"Перекресток":{"count":312},"Maxima X":{"count":117},"Карусель":{"count":55},"ALDI Nord":{"count":51},"Condis":{"count":67},"Sam's Club":{"count":138},"Копейка":{"count":87},"Géant Casino":{"count":54},"ASDA":{"count":180},"Intermarche":{"count":115},"Stop & Shop":{"count":66},"Food Lion":{"count":216},"Harris Teeter":{"count":92},"Foodworks":{"count":62},"Polo Market":{"count":86},"Лента":{"count":51},"西友 (SEIYU)":{"count":58},"H-E-B":{"count":293},"Атак":{"count":53},"Полушка":{"count":139},"Extra":{"count":82},"Lewiatan":{"count":94},"Sigma":{"count":51},"АТБ":{"count":322},"Społem":{"count":55},"Bodega Aurrera":{"count":82},"Tesco Lotus":{"count":77},"Мария-Ра":{"count":108},"Магнолия":{"count":72},"Магазин":{"count":120},"Монетка":{"count":174},"Hy-Vee":{"count":75},"Walmart Supercenter":{"count":133},"Hannaford":{"count":57},"Wegmans":{"count":83},"業務スーパー":{"count":61},"Norfa XL":{"count":55},"ヨークマート (YorkMart)":{"count":64},"Leclerc Drive":{"count":76}},"electronics":{"Media Markt":{"count":285},"Maplin":{"count":65},"Best Buy":{"count":345},"Future Shop":{"count":73},"Saturn":{"count":134},"Currys":{"count":80},"Radio Shack":{"count":269},"Euronics":{"count":115},"Expert":{"count":123},"Эльдорадо":{"count":184},"Darty":{"count":74},"М.Видео":{"count":89},"ヤマダ電機":{"count":51}},"convenience":{"Shell":{"count":255},"Spar":{"count":1119},"McColl's":{"count":100},"Tesco Express":{"count":426},"Sainsbury's Local":{"count":104},"Aral":{"count":56},"One Stop":{"count":146},"The Co-operative Food":{"count":115},"Londis":{"count":352},"7-Eleven":{"count":4440},"CBA":{"count":135},"Coop":{"count":678},"Sale":{"count":80},"Statoil":{"count":69},"Sheetz":{"count":54},"Konzum":{"count":173},"Siwa":{"count":216},"Mercator":{"count":57},"Esso":{"count":67},"COOP Jednota":{"count":181},"Mac's":{"count":152},"Alepa":{"count":62},"Hasty Market":{"count":54},"K-Market":{"count":54},"Costcutter":{"count":292},"Valintatalo":{"count":62},"Casino":{"count":90},"Franprix":{"count":61},"Circle K":{"count":289},"セブンイレブン":{"count":3011,"tags":{"name:en":"7-Eleven"}},"ローソン":{"count":1596,"tags":{"name:en":"LAWSON"}},"BP":{"count":163},"Tesco":{"count":55},"Petit Casino":{"count":233},"Volg":{"count":116},"Mace":{"count":115},"Mini Market":{"count":272},"Nisa Local":{"count":77},"Dorfladen":{"count":75},"Продукты":{"count":4285},"Mini Stop":{"count":228},"LAWSON":{"count":419},"デイリーヤマザキ":{"count":141},"Biedronka":{"count":83},"Надежда":{"count":56},"Mobil":{"count":66},"Nisa":{"count":51},"Premier":{"count":129},"ABC":{"count":152},"ミニストップ":{"count":316,"tags":{"name:en":"MINISTOP"}},"サンクス":{"count":560,"tags":{"name:en":"sunkus"}},"スリーエフ":{"count":88},"8 à Huit":{"count":61},"Tchibo":{"count":56},"Żabka":{"count":546},"Almacen":{"count":229},"Vival":{"count":194},"FamilyMart":{"count":529},"ファミリーマート":{"count":1608,"tags":{"name:en":"FamilyMart"}},"Carrefour City":{"count":57},"Sunkus":{"count":62},"Casey's General Store":{"count":95},"セブンイレブン(Seven-Eleven)":{"count":65},"Jednota":{"count":58},"Магазин":{"count":915},"Гастроном":{"count":152},"Centra":{"count":111},"Магнит":{"count":701},"サークルK":{"count":538,"tags":{"name:en":"Circle K"}},"Wawa":{"count":135},"Proxi":{"count":123},"Универсам":{"count":78},"Перекресток":{"count":51},"Groszek":{"count":65},"Select":{"count":62},"Večerka":{"count":51},"Potraviny":{"count":249},"Смак":{"count":78},"Эконом":{"count":55},"Березка":{"count":77},"Społem":{"count":93},"Carrefour Express":{"count":84},"Cumberland Farms":{"count":63},"Chevron":{"count":59},"Coop Jednota":{"count":66},"Tesco Lotus Express":{"count":67},"Kiosk":{"count":55},"Sklep spożywczy":{"count":130},"24 часа":{"count":58},"Минимаркет":{"count":102},"Oxxo":{"count":669},"Пятёрочка":{"count":398},"abc":{"count":74},"7/11":{"count":51},"Stewart's":{"count":255},"Продукти":{"count":171},"ローソンストア100 (LAWSON STORE 100)":{"count":85},"Дикси":{"count":119},"Радуга":{"count":86},"ローソンストア100":{"count":76},"เซเว่นอีเลฟเว่น":{"count":185},"Delikatesy Centrum":{"count":53},"Citgo":{"count":62},"Фортуна":{"count":51},"Kum & Go":{"count":59},"Мария-Ра":{"count":76},"Picard":{"count":57},"Four Square":{"count":52},"Визит":{"count":57},"Авоська":{"count":55},"Dollar General":{"count":127},"Studenac":{"count":76},"Central Convenience Store":{"count":55},"Монетка":{"count":62},"продукты":{"count":114},"Теремок":{"count":56},"Kwik Trip":{"count":69},"Кулинария":{"count":55},"全家":{"count":90},"Мечта":{"count":54},"Epicerie":{"count":102},"Кировский":{"count":67},"Food Mart":{"count":117},"Delikatesy":{"count":81},"ポプラ":{"count":54},"Lewiatan":{"count":135},"Продуктовый магазин":{"count":149},"Продуктовый":{"count":84},"セイコーマート (Seicomart)":{"count":72},"Виктория":{"count":70},"Весна":{"count":57},"Mini Market Non-Stop":{"count":60},"QuikTrip":{"count":75},"Копеечка":{"count":51},"Royal Farms":{"count":51},"Alfamart":{"count":103},"Indomaret":{"count":141},"магазин":{"count":171},"全家便利商店":{"count":156},"Boutique":{"count":59},"მარკეტი (Market)":{"count":144},"Stores":{"count":61}},"chemist":{"dm":{"count":939},"Müller":{"count":212},"Schlecker":{"count":187},"Etos":{"count":467},"Bipa":{"count":289},"Rossmann":{"count":1669},"DM Drogeriemarkt":{"count":55},"Ihr Platz":{"count":73},"Douglas":{"count":62},"Kruidvat":{"count":123}},"car_repair":{"Peugeot":{"count":83},"Kwik Fit":{"count":128},"ATU":{"count":261},"Midas":{"count":202},"Feu Vert":{"count":113},"Norauto":{"count":152},"Speedy":{"count":115},"Автозапчасти":{"count":212},"Renault":{"count":171},"Pit Stop":{"count":58},"Jiffy Lube":{"count":198},"Шиномонтаж":{"count":1157},"СТО":{"count":395},"O'Reilly Auto Parts":{"count":81},"Carglass":{"count":112},"шиномонтаж":{"count":62},"Citroen":{"count":51},"Euromaster":{"count":87},"Firestone":{"count":88},"Автосервис":{"count":361},"Advance Auto Parts":{"count":52},"Roady":{"count":56}},"furniture":{"IKEA":{"count":169},"Jysk":{"count":109},"Roller":{"count":78},"Dänisches Bettenlager":{"count":309},"Conforama":{"count":99},"Matratzen Concord":{"count":52},"Мебель":{"count":210},"But":{"count":63}},"doityourself":{"Hornbach":{"count":123},"B&Q":{"count":225},"Hubo":{"count":77},"Mr Bricolage":{"count":88},"Gamma":{"count":111},"OBI":{"count":422},"Lowes":{"count":1152},"Wickes":{"count":123},"Hagebau":{"count":59},"Max Bahr":{"count":79},"Castorama":{"count":153},"Rona":{"count":61},"Home Depot":{"count":865},"Toom Baumarkt":{"count":71},"Homebase":{"count":225},"Baumax":{"count":95},"Lagerhaus":{"count":79},"Bauhaus":{"count":186},"Canadian Tire":{"count":97},"Leroy Merlin":{"count":209},"Hellweg":{"count":58},"Brico":{"count":98},"Bricomarché":{"count":235},"Toom":{"count":67},"Hagebaumarkt":{"count":107},"Praktiker":{"count":122},"Menards":{"count":70},"Weldom":{"count":73},"Bunnings Warehouse":{"count":91},"Ace Hardware":{"count":147},"Home Hardware":{"count":72},"Хозтовары":{"count":86},"Стройматериалы":{"count":197},"Bricorama":{"count":60},"Point P":{"count":59}},"stationery":{"Staples":{"count":299},"McPaper":{"count":83},"Office Depot":{"count":98},"Канцтовары":{"count":63}},"car":{"Skoda":{"count":97},"BMW":{"count":149},"Citroen":{"count":277},"Renault":{"count":382},"Mercedes-Benz":{"count":235},"Volvo":{"count":96},"Ford":{"count":239},"Volkswagen":{"count":217},"Mazda":{"count":105},"Mitsubishi":{"count":73},"Fiat":{"count":93},"Автозапчасти":{"count":277},"Opel":{"count":165},"Audi":{"count":121},"Toyota":{"count":271},"Nissan":{"count":189},"Suzuki":{"count":75},"Honda":{"count":157},"Peugeot":{"count":308},"Шиномонтаж":{"count":259},"Hyundai":{"count":166},"Subaru":{"count":58},"Chevrolet":{"count":86},"Автомагазин":{"count":72}},"clothes":{"Matalan":{"count":90},"KiK":{"count":1219},"H&M":{"count":658},"Urban Outfitters":{"count":63},"Vögele":{"count":132},"Zeeman":{"count":121},"Takko":{"count":515},"Adler":{"count":55},"C&A":{"count":506},"Zara":{"count":217},"Vero Moda":{"count":95},"NKD":{"count":486},"Ernsting's family":{"count":312},"Winners":{"count":65},"River Island":{"count":59},"Next":{"count":176},"Gap":{"count":81},"Adidas":{"count":92},"Woolworths":{"count":117},"Mr Price":{"count":88},"Jet":{"count":61},"Pep":{"count":134},"Edgars":{"count":110},"Ackermans":{"count":91},"Truworths":{"count":65},"Ross":{"count":93},"Burton":{"count":51},"Dorothy Perkins":{"count":53},"Deichmann":{"count":61},"Lindex":{"count":73},"s.Oliver":{"count":56},"Cecil":{"count":51},"Dress Barn":{"count":52},"Old Navy":{"count":174},"Jack & Jones":{"count":52},"Pimkie":{"count":73},"Esprit":{"count":231},"Primark":{"count":92},"Bonita":{"count":155},"Mexx":{"count":67},"Gerry Weber":{"count":71},"Tally Weijl":{"count":70},"Mango":{"count":133},"TK Maxx":{"count":84},"Benetton":{"count":101},"Ulla Popken":{"count":61},"AWG":{"count":66},"Tommy Hilfiger":{"count":75},"New Yorker":{"count":180},"Orsay":{"count":73},"Jeans Fritz":{"count":51},"Charles Vögele":{"count":69},"New Look":{"count":126},"Lacoste":{"count":78},"Etam":{"count":53},"Kiabi":{"count":148},"Jack Wolfskin":{"count":60},"American Apparel":{"count":57},"Men's Wearhouse":{"count":54},"Intimissimi":{"count":52},"United Colors of Benetton":{"count":96},"Jules":{"count":63},"Second Hand":{"count":53},"AOKI":{"count":57},"Calzedonia":{"count":68},"洋服の青山":{"count":100},"Levi's":{"count":63},"Celio":{"count":74},"TJ Maxx":{"count":57},"Promod":{"count":82},"Street One":{"count":72},"ユニクロ":{"count":59},"Banana Republic":{"count":57},"Одежда":{"count":75},"Marshalls":{"count":56},"La Halle":{"count":62},"Peacocks":{"count":89},"しまむら":{"count":60}},"books":{"Bruna":{"count":58},"Waterstones":{"count":90},"Libro":{"count":57},"Barnes & Noble":{"count":267},"Weltbild":{"count":74},"Thalia":{"count":121},"Книги":{"count":112}},"department_store":{"Debenhams":{"count":67},"Canadian Tire":{"count":75},"Karstadt":{"count":64},"Walmart":{"count":517},"Kmart":{"count":143},"Target":{"count":574},"Galeria Kaufhof":{"count":61},"Marks & Spencer":{"count":66},"Big W":{"count":57},"Woolworth":{"count":78},"Универмаг":{"count":72},"Sears":{"count":235},"Walmart Supercenter":{"count":101},"Kohl's":{"count":153},"Macy's":{"count":147},"Sam's Club":{"count":54},"JCPenney":{"count":66}},"alcohol":{"Alko":{"count":145},"The Beer Store":{"count":150},"Systembolaget":{"count":210},"LCBO":{"count":239},"Ароматный мир":{"count":62},"Bargain Booze":{"count":62},"Nicolas":{"count":119},"BWS":{"count":70},"Botilleria":{"count":77},"SAQ":{"count":72},"Gall & Gall":{"count":512},"Живое пиво":{"count":70}},"bakery":{"Kamps":{"count":252},"Banette":{"count":52},"Bäckerei Schmidt":{"count":57},"Anker":{"count":73},"Hofpfisterei":{"count":111},"Greggs":{"count":276},"Oebel":{"count":57},"Boulangerie":{"count":266},"Stadtbäckerei":{"count":57},"Steinecke":{"count":145},"Ihle":{"count":76},"Goldilocks":{"count":59},"Dat Backhus":{"count":67},"K&U":{"count":61},"Der Beck":{"count":96},"Thürmann":{"count":54},"Backwerk":{"count":95},"Schäfer's":{"count":51},"Panaderia":{"count":168},"Goeken backen":{"count":51},"Stadtbäckerei Junge":{"count":51},"Boulangerie Patisserie":{"count":119},"Paul":{"count":81},"Хлеб":{"count":89},"Пекарня":{"count":52},"Кулиничи":{"count":51}},"sports":{"Sports Direct":{"count":57},"Decathlon":{"count":309},"Intersport":{"count":283},"Sports Authority":{"count":75},"Спортмастер":{"count":87},"Sport 2000":{"count":90},"Dick's Sporting Goods":{"count":77}},"variety_store":{"Tedi":{"count":157},"Dollarama":{"count":103},"Family Dollar":{"count":61},"Dollar Tree":{"count":110},"Dollar General":{"count":80}},"pet":{"Fressnapf":{"count":318},"PetSmart":{"count":177},"Das Futterhaus":{"count":69},"Pets at Home":{"count":62},"Petco":{"count":101},"Зоомагазин":{"count":100}},"shoes":{"Deichmann":{"count":622},"Reno":{"count":183},"Ecco":{"count":55},"Clarks":{"count":109},"La Halle aux Chaussures":{"count":69},"Brantano":{"count":71},"Geox":{"count":51},"Salamander":{"count":51},"Обувь":{"count":100},"Payless Shoe Source":{"count":67},"Famous Footwear":{"count":59},"Quick Schuh":{"count":72},"Shoe Zone":{"count":55},"Foot Locker":{"count":82},"Bata":{"count":101},"ЦентрОбувь":{"count":51}},"toys":{"La Grande Récré":{"count":56},"Toys R Us":{"count":151,"tags":{"shop":"toys"}},"Intertoys":{"count":57},"Детский мир":{"count":86},"Игрушки":{"count":58}},"travel_agency":{"Flight Centre":{"count":92},"Thomas Cook":{"count":119}},"jewelry":{"Bijou Brigitte":{"count":57},"Christ":{"count":57},"Swarovski":{"count":74}},"optician":{"Fielmann":{"count":232},"Apollo Optik":{"count":150},"Vision Express":{"count":58},"Оптика":{"count":182},"Optic 2000":{"count":98},"Alain Afflelou":{"count":73},"Specsavers":{"count":124},"Krys":{"count":77},"Atol":{"count":55}},"video":{"Blockbuster":{"count":184},"World of Video":{"count":64}},"mobile_phone":{"Билайн":{"count":128},"ソフトバンクショップ (SoftBank shop)":{"count":255},"Vodafone":{"count":355},"O2":{"count":208},"Carphone Warehouse":{"count":127},"Orange":{"count":246},"Verizon Wireless":{"count":125},"Sprint":{"count":109},"T-Mobile":{"count":175},"МТС":{"count":352},"Евросеть":{"count":506},"Bell":{"count":190},"The Phone House":{"count":83},"SFR":{"count":71},"Связной":{"count":439},"Мегафон":{"count":251},"AT&T":{"count":124},"ドコモショップ (docomo shop)":{"count":114},"au":{"count":65},"Movistar":{"count":77},"Bitė":{"count":72}},"hifi":{},"computer":{"PC World":{"count":55},"DNS":{"count":128}},"hairdresser":{"Klier":{"count":119},"Supercuts":{"count":106},"Hairkiller":{"count":51},"Great Clips":{"count":182},"Парикмахерская":{"count":510},"Стиль":{"count":51},"Franck Provost":{"count":70},"Салон красоты":{"count":70}},"hardware":{"1000 мелочей":{"count":61},"Хозтовары":{"count":151},"Стройматериалы":{"count":54}},"motorcycle":{"Yamaha":{"count":67},"Honda":{"count":69}}};
18929 var dataSuggestions = {
18934 var dataAddressFormats = [{"format":[["housenumber","street"],["city","postcode"]]},{"countryCodes":["gb"],"format":[["housename"],["housenumber","street"],["city","postcode"]]},{"countryCodes":["ie"],"format":[["housename"],["housenumber","street"],["city"],["postcode"]]},{"countryCodes":["ad","at","ba","be","ch","cz","de","dk","es","fi","gr","hr","is","it","li","nl","no","pl","pt","se","si","sk","sm","va"],"format":[["street","housenumber"],["postcode","city"]]},{"countryCodes":["fr","lu","mo"],"format":[["housenumber","street"],["postcode","city"]]},{"countryCodes":["br"],"format":[["street"],["housenumber","suburb"],["city","postcode"]]},{"countryCodes":["vn"],"format":[["housenumber","street"],["subdistrict"],["district"],["city"],["province","postcode"]]},{"countryCodes":["us"],"format":[["housenumber","street"],["city","state","postcode"]]},{"countryCodes":["ca"],"format":[["housenumber","street"],["city","province","postcode"]]},{"countryCodes":["tw"],"format":[["postcode","city","district"],["place","street"],["housenumber","floor"]]}];
18936 var dataDeprecated = [{"old":{"amenity":"firepit"},"replace":{"leisure":"firepit"}},{"old":{"barrier":"wire_fence"},"replace":{"barrier":"fence","fence_type":"chain"}},{"old":{"barrier":"wood_fence"},"replace":{"barrier":"fence","fence_type":"wood"}},{"old":{"highway":"ford"},"replace":{"ford":"yes"}},{"old":{"highway":"stile"},"replace":{"barrier":"stile"}},{"old":{"highway":"incline"},"replace":{"highway":"road","incline":"up"}},{"old":{"highway":"incline_steep"},"replace":{"highway":"road","incline":"up"}},{"old":{"highway":"unsurfaced"},"replace":{"highway":"road","incline":"unpaved"}},{"old":{"landuse":"wood"},"replace":{"landuse":"forest","natural":"wood"}},{"old":{"natural":"marsh"},"replace":{"natural":"wetland","wetland":"marsh"}},{"old":{"power_source":"*"},"replace":{"generator:source":"$1"}},{"old":{"power_rating":"*"},"replace":{"generator:output":"$1"}},{"old":{"shop":"organic"},"replace":{"shop":"supermarket","organic":"only"}}];
18938 var dataDiscarded = ["created_by","odbl","odbl:note","tiger:upload_uuid","tiger:tlid","tiger:source","tiger:separated","geobase:datasetName","geobase:uuid","sub_sea:type","KSJ2:ADS","KSJ2:ARE","KSJ2:AdminArea","KSJ2:COP_label","KSJ2:DFD","KSJ2:INT","KSJ2:INT_label","KSJ2:LOC","KSJ2:LPN","KSJ2:OPC","KSJ2:PubFacAdmin","KSJ2:RAC","KSJ2:RAC_label","KSJ2:RIC","KSJ2:RIN","KSJ2:WSC","KSJ2:coordinate","KSJ2:curve_id","KSJ2:curve_type","KSJ2:filename","KSJ2:lake_id","KSJ2:lat","KSJ2:long","KSJ2:river_id","yh:LINE_NAME","yh:LINE_NUM","yh:STRUCTURE","yh:TOTYUMONO","yh:TYPE","yh:WIDTH","yh:WIDTH_RANK","SK53_bulk:load"];
18940 var dataLocales = ["af","sq","ar","ar-AA","hy","ast","bn","bs","bg-BG","ca","zh","zh-CN","zh-HK","zh-TW","yue","hr","cs","da","nl","en-GB","eo","et","fi","fr","gl","de","el","gu","hi","hu","is","id","it","ja","kn","ko","ku","lv","lij","lt","ml","no","fa","pl","pt","pt-BR","ro","ru","sc","sr","si","sk","sl","es","sv","tl","ta","te","th","tr","uk","vi"];
18942 var dataPhoneFormats = {"us":"+1-202-555-1234","ca":"+1-226-555-1234","bs":"+1-242-555-1234","bb":"+1-246-555-1234","ai":"+1-264-555-1234","ag":"+1-268-555-1234","vg":"+1-284-555-1234","vi":"+1-340-555-1234","ky":"+1-345-555-1234","bm":"+1-441-555-1234","gd":"+1-473-555-1234","tc":"+1-649-555-1234","ms":"+1-664-555-1234","mp":"+1-670-555-1234","gu":"+1-671-555-1234","as":"+1-684-555-1234","sx":"+1-721-555-1234","lc":"+1-758-555-1234","dm":"+1-767-555-1234","vc":"+1-784-555-1234","pr":"+1-787-555-1234","do":"+1-809-555-1234","tt":"+1-868-555-1234","kn":"+1-869-555-1234","jm":"+1-876-555-1234","za":"+27 11 907 1111","nl":"+31 42 123 4567","fr":"+33 1 23 45 67 89","es":"+34 989 12 34 56","pt":"+351 211 123456","fi":"+358 40 123 4567","hu":"+36 1 123 45 67","hr":"+385 01 123 4567","si":"+386 31 123 4567","it":"+39 01 123 456","va":"+39 01 123 456","gb":"+44 207 123456","gg":"+44 207 123456","im":"+44 207 123456","je":"+44 207 123456","se":"+46 31 123 4567","no":"+47 22 12 34 56","sj":"+47 22 12 34 56","pl":"+48 42 123 4567","de":"+49 89 1234567","br":"+55 11 0982 1098","ru":"+7 495 1234567","kz":"+7 495 1234567","vn":"+84 1 234 5678","hk":"+852 12345678"};
18944 var type = "FeatureCollection";
18945 var features = [{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[1.97754,51.13111],[1.8457,63.45051],[-10.45898,57.01681],[-6.82251,55.26503],[-7.25583,55.06525],[-7.26546,55.0665],[-7.26992,55.06419],[-7.2725,55.06346],[-7.27818,55.05362],[-7.2893,55.04735],[-7.29939,55.0561],[-7.31835,55.04475],[-7.3447,55.05079],[-7.38831,55.02389],[-7.40547,55.00292],[-7.39157,54.99507],[-7.40075,54.98892],[-7.40706,54.98291],[-7.40363,54.97963],[-7.40633,54.97813],[-7.39835,54.97013],[-7.40745,54.96357],[-7.40178,54.95961],[-7.40727,54.95515],[-7.3944,54.94376],[-7.44444,54.93858],[-7.45216,54.89793],[-7.44204,54.87532],[-7.4713,54.83431],[-7.48092,54.83093],[-7.49216,54.82185],[-7.55121,54.79054],[-7.5443,54.78609],[-7.54958,54.75653],[-7.5349,54.74917],[-7.54881,54.74068],[-7.55941,54.74556],[-7.57894,54.74221],[-7.57507,54.7494],[-7.58606,54.75039],[-7.58872,54.74377],[-7.60031,54.74603],[-7.60632,54.74405],[-7.61662,54.74459],[-7.63593,54.75108],[-7.68854,54.72968],[-7.72064,54.72155],[-7.75094,54.70469],[-7.79094,54.71942],[-7.8051,54.71932],[-7.83497,54.73632],[-7.85419,54.72745],[-7.91496,54.67582],[-7.90174,54.66182],[-7.83832,54.63401],[-7.7433,54.6188],[-7.70863,54.63485],[-7.70682,54.6189],[-7.69386,54.6188],[-7.69631,54.61125],[-7.75845,54.59509],[-7.78708,54.58],[-7.79446,54.58141],[-7.79969,54.57704],[-7.79673,54.56915],[-7.8184,54.56315],[-7.83334,54.55227],[-7.82737,54.54299],[-7.85007,54.53363],[-7.90741,54.53722],[-7.93213,54.53388],[-8.00487,54.54568],[-8.03727,54.51162],[-8.04285,54.48759],[-8.08027,54.48829],[-8.09988,54.48395],[-8.09126,54.4765],[-8.111,54.47807],[-8.11512,54.46904],[-8.16542,54.46914],[-8.1776,54.46485],[-8.14293,54.45003],[-8.16284,54.4413],[-8.08731,54.4002],[-8.06062,54.37051],[-8.03289,54.35711],[-8.00054,54.34835],[-7.93333,54.30561],[-7.85849,54.29151],[-7.87067,54.28794],[-7.87265,54.26648],[-7.86123,54.25931],[-7.85917,54.21256],[-7.71043,54.20307],[-7.70193,54.20776],[-7.68828,54.202],[-7.67644,54.18906],[-7.66082,54.1871],[-7.62554,54.16545],[-7.62541,54.15319],[-7.61026,54.14353],[-7.57421,54.14142],[-7.57181,54.13287],[-7.56228,54.12704],[-7.51379,54.12998],[-7.47944,54.122],[-7.47169,54.12665],[-7.47075,54.13318],[-7.44684,54.15168],[-7.40792,54.156],[-7.42579,54.14092],[-7.41903,54.13629],[-7.3744,54.14172],[-7.37234,54.13881],[-7.39509,54.12624],[-7.39182,54.12017],[-7.36341,54.13157],[-7.34518,54.11577],[-7.32471,54.12123],[-7.32003,54.11379],[-7.3078,54.11718],[-7.30548,54.12347],[-7.31591,54.12697],[-7.31213,54.13162],[-7.3187,54.13411],[-7.31857,54.13745],[-7.32222,54.13836],[-7.32737,54.13544],[-7.3399,54.14585],[-7.30827,54.16716],[-7.30024,54.16625],[-7.29029,54.1715],[-7.28158,54.16839],[-7.2863,54.14919],[-7.29874,54.14904],[-7.30162,54.14411],[-7.28411,54.13971],[-7.29192,54.13071],[-7.29737,54.133],[-7.30883,54.13242],[-7.30333,54.12251],[-7.29218,54.11929],[-7.27844,54.12282],[-7.27707,54.12986],[-7.26613,54.13624],[-7.2566,54.16354],[-7.24015,54.17125],[-7.2575,54.17678],[-7.2581,54.19257],[-7.25179,54.19403],[-7.23608,54.1935],[-7.23338,54.19792],[-7.24317,54.20076],[-7.24892,54.1977],[-7.25183,54.20201],[-7.24119,54.20623],[-7.23094,54.20578],[-7.23269,54.20912],[-7.22188,54.21607],[-7.20643,54.2117],[-7.18506,54.22485],[-7.17055,54.21742],[-7.14721,54.22488],[-7.14633,54.23008],[-7.15051,54.23165],[-7.14613,54.23983],[-7.15802,54.24434],[-7.13985,54.25298],[-7.15255,54.26235],[-7.16064,54.27405],[-7.17991,54.27144],[-7.17201,54.28627],[-7.21252,54.2985],[-7.19888,54.31117],[-7.17918,54.30946],[-7.1812,54.3397],[-7.15339,54.33514],[-7.10253,54.35811],[-7.10811,54.36677],[-7.06927,54.3899],[-7.05593,54.41056],[-7.02898,54.42135],[-7.00198,54.40832],[-6.98683,54.40829],[-6.97562,54.40014],[-6.96774,54.40145],[-6.90682,54.36966],[-6.89772,54.35075],[-6.87527,54.33853],[-6.86512,54.32568],[-6.85163,54.29137],[-6.87452,54.28677],[-6.87791,54.27918],[-6.86673,54.27522],[-6.85177,54.26489],[-6.83693,54.26658],[-6.82165,54.24346],[-6.81633,54.22299],[-6.80045,54.22108],[-6.80122,54.21338],[-6.77599,54.19965],[-6.75573,54.1987],[-6.74316,54.18258],[-6.73406,54.18566],[-6.72445,54.18127],[-6.70295,54.20036],[-6.69166,54.20018],[-6.68673,54.19398],[-6.669,54.19584],[-6.65248,54.18102],[-6.6433,54.17801],[-6.63467,54.16449],[-6.63179,54.14766],[-6.64081,54.14238],[-6.63935,54.13599],[-6.66149,54.1205],[-6.6481,54.10153],[-6.66119,54.0934],[-6.66458,54.06629],[-6.64681,54.05873],[-6.62501,54.03737],[-6.59291,54.04755],[-6.58905,54.05808],[-6.5597,54.0481],[-6.52897,54.05888],[-6.50442,54.05566],[-6.47824,54.07004],[-6.47919,54.07762],[-6.43601,54.05959],[-6.36314,54.07057],[-6.36589,54.09338],[-6.36293,54.09758],[-6.37104,54.11497],[-6.3522,54.11084],[-6.34242,54.1114],[-6.33589,54.10833],[-6.33636,54.09469],[-6.31808,54.09096],[-6.30903,54.10463],[-6.29165,54.11235],[-6.28246,54.11145],[-6.26272,54.09786],[-5.35583,53.72597],[-7.0752,49.23912],[-1.83472,49.02346],[-2.12036,49.94415],[1.97754,51.13111]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-65.2,18.7],[-65,16.3],[-63.7,19.2],[-65.2,18.7]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-63,-50.5],[-55,-51],[-60,-54],[-63,-50.5]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-139.19952,60.08402],[-141,60.30621],[-141,76],[-169,68.63655],[-169,65.20147],[-180,61],[-180,-4],[-154,9],[-133.76404,54.54021],[-130.73868,54.71986],[-129.96277,55.29163],[-130.15228,55.7758],[-130.01787,55.90688],[-130.00362,56.00798],[-130.10284,56.12336],[-130.24498,56.09656],[-130.42625,56.14249],[-131.87439,56.79787],[-135.02884,59.56285],[-135.11759,59.62306],[-135.15827,59.6261],[-135.47928,59.79822],[-136.28677,59.57955],[-136.30531,59.46462],[-136.36836,59.44898],[-136.47697,59.46558],[-137.19727,59.01935],[-139.19952,60.08402]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-111.96064,48.99841],[-121.22623,49.00049],[-122.26513,49.00246],[-122.7565,49.00208],[-123.32218,49.00218],[-122.97821,48.76524],[-123.2666,48.69821],[-123.21991,48.21186],[-125.80444,48.60749],[-124.32129,31.54109],[-117.125,32.53429],[-116.82417,32.55996],[-115.88036,32.63735],[-115.49738,32.66486],[-114.71984,32.71877],[-114.7649,32.64602],[-114.80885,32.60959],[-114.81481,32.49451],[-112.81743,31.88004],[-111.07481,31.33224],[-109.56051,31.33402],[-108.20847,31.33384],[-108.20838,31.78363],[-106.52847,31.78391],[-106.52781,31.78086],[-106.52249,31.77501],[-106.51249,31.76933],[-106.50988,31.7612],[-106.50709,31.76123],[-106.48896,31.74806],[-106.48473,31.74769],[-106.4719,31.75101],[-106.46816,31.75897],[-106.45434,31.76466],[-106.45035,31.76426],[-106.43516,31.75492],[-106.41484,31.75101],[-106.37864,31.73021],[-106.37225,31.71174],[-106.34924,31.69633],[-106.33289,31.66178],[-106.3068,31.62459],[-106.28079,31.56179],[-106.24775,31.54226],[-106.2329,31.49982],[-106.2105,31.46857],[-106.08201,31.39863],[-106.00554,31.39233],[-105.76401,31.17051],[-105.58548,31.06117],[-105.56419,30.98526],[-104.99153,30.6639],[-104.97162,30.60896],[-104.90639,30.57822],[-104.83772,30.38117],[-104.70177,30.20567],[-104.68048,29.92399],[-104.57611,29.77838],[-104.51157,29.63674],[-104.39758,29.57047],[-104.39278,29.55293],[-104.05769,29.32173],[-103.79883,29.2581],[-103.78196,29.26555],[-103.76759,29.22799],[-103.14102,28.93666],[-102.86087,29.2217],[-102.65076,29.79418],[-101.41068,29.73457],[-101.26511,29.51372],[-101.05997,29.452],[-101.04083,29.38038],[-100.96303,29.34735],[-100.94406,29.34369],[-100.94071,29.33351],[-100.92775,29.32663],[-100.89814,29.30957],[-100.87818,29.28086],[-100.80076,29.2238],[-100.76437,29.15981],[-100.67047,29.08663],[-100.6412,28.91299],[-100.63236,28.90255],[-100.61296,28.89939],[-100.534,28.75622],[-100.51495,28.74531],[-100.50705,28.7143],[-100.51203,28.70666],[-100.51014,28.69127],[-100.50048,28.66186],[-100.45547,28.6381],[-100.44697,28.60743],[-100.35599,28.45239],[-100.34946,28.39653],[-100.29488,28.31315],[-100.29591,28.27324],[-100.17197,28.17493],[-99.93645,27.9568],[-99.87722,27.80173],[-99.79671,27.73338],[-99.772,27.72532],[-99.74556,27.69979],[-99.71947,27.65981],[-99.5957,27.59974],[-99.54094,27.60537],[-99.53055,27.57973],[-99.52034,27.55782],[-99.52802,27.49773],[-99.50141,27.49986],[-99.48755,27.49518],[-99.47897,27.48421],[-99.48661,27.46453],[-99.49534,27.44861],[-99.48927,27.40941],[-99.53957,27.31565],[-99.43588,27.19678],[-99.46404,27.01968],[-99.16698,26.56039],[-99.17474,26.53939],[-99.12698,26.51958],[-99.1135,26.42954],[-99.08355,26.39625],[-99.06007,26.39737],[-99.03634,26.41255],[-99.02042,26.40598],[-99.01291,26.39364],[-98.95686,26.38641],[-98.9566,26.37365],[-98.94523,26.36949],[-98.90013,26.36419],[-98.89905,26.35454],[-98.80305,26.36626],[-98.78254,26.30511],[-98.66667,26.23457],[-98.58496,26.24647],[-98.57951,26.23434],[-98.56519,26.23987],[-98.56294,26.22464],[-98.50599,26.20858],[-98.44806,26.21236],[-98.38617,26.15721],[-98.34176,26.15278],[-98.33579,26.1388],[-98.30626,26.10003],[-98.28841,26.10512],[-98.26524,26.0914],[-98.19898,26.06411],[-98.09577,26.05698],[-98.07568,26.06667],[-98.08302,26.03396],[-97.9771,26.04136],[-97.9532,26.06179],[-97.81643,26.04475],[-97.77017,26.02439],[-97.73884,26.02902],[-97.5289,25.90648],[-97.52151,25.88625],[-97.50615,25.89031],[-97.49851,25.89903],[-97.49637,25.89641],[-97.49748,25.88008],[-97.49422,25.87981],[-97.48847,25.88564],[-97.46409,25.88174],[-97.42607,25.842],[-97.36856,25.8396],[-97.26231,25.94724],[-80.81543,24.00633],[-66.87378,44.77794],[-67.16148,45.16715],[-67.2286,45.16739],[-67.26246,45.18797],[-67.28311,45.19175],[-67.28959,45.18784],[-67.29332,45.17568],[-67.29049,45.17317],[-67.3001,45.16776],[-67.3025,45.16122],[-67.29761,45.14766],[-67.33975,45.1255],[-67.40524,45.16122],[-67.40387,45.17139],[-67.4818,45.27682],[-67.42172,45.38543],[-67.45262,45.41008],[-67.50498,45.4889],[-67.41623,45.50105],[-67.42219,45.55661],[-67.42902,45.56833],[-67.42331,45.57154],[-67.42498,45.57836],[-67.45193,45.60323],[-67.77981,45.6738],[-67.79019,47.06776],[-67.88006,47.1067],[-67.91319,47.14793],[-67.92598,47.15418],[-67.95181,47.1875],[-68.02374,47.23915],[-68.13017,47.29309],[-68.17669,47.32893],[-68.24046,47.35354],[-68.32809,47.36005],[-68.36363,47.35476],[-68.38054,47.34167],[-68.38509,47.30321],[-68.37367,47.28796],[-68.4377,47.28232],[-68.47916,47.29623],[-68.51074,47.29885],[-68.54593,47.28441],[-68.58408,47.28482],[-68.59777,47.27134],[-68.59271,47.25762],[-68.61889,47.24148],[-68.68936,47.24125],[-68.71768,47.23676],[-68.80128,47.21423],[-68.89629,47.17676],[-69.05354,47.24847],[-69.04924,47.41798],[-69.22425,47.45961],[-69.99729,46.69558],[-70.0569,46.4149],[-70.25551,46.10871],[-70.29001,46.09431],[-70.39919,45.80667],[-70.83229,45.40062],[-70.80794,45.37878],[-70.82663,45.2367],[-70.87538,45.23453],[-70.92138,45.28099],[-70.90645,45.30918],[-71.0109,45.34798],[-71.08429,45.30556],[-71.1454,45.24226],[-71.20525,45.25278],[-71.28925,45.30097],[-71.41405,45.23513],[-71.43044,45.12381],[-71.49692,45.06991],[-71.50623,45.04878],[-71.49284,45.03629],[-71.50027,45.01372],[-71.79359,45.01075],[-72.08774,45.00581],[-72.14155,45.00568],[-72.15282,45.00609],[-72.17142,45.00584],[-72.25847,45.00436],[-72.38795,45.00626],[-72.4496,45.00863],[-72.5356,45.00936],[-72.66257,45.01523],[-72.82537,45.01642],[-73.08466,45.01561],[-73.45219,45.00875],[-74.14699,44.99145],[-74.33753,44.9923],[-74.50786,44.99798],[-74.66158,44.99949],[-74.71244,44.99734],[-74.75887,44.98708],[-74.76368,45.00632],[-74.78977,45.00365],[-74.82376,45.01773],[-74.94186,44.98229],[-75.30098,44.83883],[-75.30304,44.82836],[-75.59418,44.6457],[-75.97269,44.33502],[-75.97295,44.34595],[-76.00059,44.34797],[-76.17645,44.2865],[-76.18744,44.22158],[-76.88782,43.82759],[-79.16851,43.32168],[-79.05487,43.25371],[-79.05092,43.169],[-79.04603,43.16093],[-79.04208,43.13942],[-79.07002,43.12038],[-79.06015,43.114],[-79.0568,43.10474],[-79.0774,43.07861],[-78.9996,43.05484],[-79.02311,43.02071],[-79.02552,42.99473],[-78.96235,42.9573],[-78.91188,42.9426],[-78.90398,42.89181],[-82.42767,41.47978],[-83.14316,42.03807],[-83.12805,42.23843],[-83.09715,42.29052],[-83.07252,42.31515],[-82.94575,42.34332],[-82.59676,42.5479],[-82.51368,42.61785],[-82.5108,42.66464],[-82.4675,42.76415],[-82.48055,42.80573],[-82.45497,42.9284],[-82.41334,42.97099],[-82.42596,42.99536],[-82.15851,43.39507],[-83.53729,46.098],[-83.96301,46.05036],[-84.11021,46.23851],[-84.09794,46.25656],[-84.11613,46.26878],[-84.11905,46.31516],[-84.10721,46.3218],[-84.14394,46.41076],[-84.11682,46.51576],[-84.13536,46.53218],[-84.16162,46.5284],[-84.21621,46.53891],[-84.26994,46.49189],[-84.36092,46.50997],[-84.55284,46.4407],[-84.95178,46.77185],[-89.59179,48.00307],[-89.67547,48.00371],[-90.87204,48.25943],[-91.41312,48.06753],[-92.99377,48.62474],[-93.34877,48.62604],[-93.35529,48.61124],[-93.37074,48.60584],[-93.39812,48.60369],[-93.40542,48.61089],[-93.43846,48.59478],[-93.46859,48.59205],[-93.45735,48.56667],[-93.46533,48.54593],[-93.64763,48.51751],[-93.80625,48.51888],[-93.80642,48.58047],[-93.83328,48.62582],[-93.84865,48.63064],[-93.93388,48.6326],[-94.01327,48.64471],[-94.16176,48.64697],[-94.25025,48.65463],[-94.24931,48.67827],[-94.26046,48.69816],[-94.30578,48.71073],[-94.32758,48.70433],[-94.36123,48.70478],[-94.38406,48.71135],[-94.41629,48.71067],[-94.44294,48.69266],[-94.53615,48.7024],[-94.55031,48.71419],[-94.58894,48.71928],[-94.69425,48.77938],[-94.70129,48.83376],[-94.68996,48.83953],[-94.68395,48.99914],[-111.96064,48.99841]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[180,55],[170,53],[180,49],[180,55]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[143,22],[147,22],[147,12],[143,12],[143,22]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-171.5,-10],[-171,-15],[-167,-15],[-171.5,-10]]]}}];
18946 var dataImperial = {
18951 var type$1 = "FeatureCollection";
18952 var features$1 = [{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[113.573,22.186],[114,22.5],[114.05534,22.503],[114.0595,22.51422],[114.07345,22.51934],[114.0786,22.53012],[114.08512,22.53228],[114.09034,22.53717],[114.09611,22.53486],[114.10602,22.53472],[114.1115,22.52929],[114.11522,22.5308],[114.11649,22.53418],[114.11979,22.53511],[114.1244,22.5393],[114.12729,22.53947],[114.13018,22.54132],[114.13807,22.5432],[114.14429,22.54176],[114.14441,22.54114],[114.14846,22.54179],[114.14855,22.54397],[114.15042,22.54593],[114.14964,22.54954],[114.15166,22.55168],[114.15192,22.55438],[114.15642,22.55495],[114.15841,22.55909],[114.16032,22.56153],[114.16162,22.56187],[114.1634,22.55931],[114.16553,22.5593],[114.16733,22.56119],[114.16934,22.56093],[114.17061,22.5597],[114.17702,22.56],[114.17798,22.55546],[114.18401,22.5552],[114.18673,22.55468],[114.1878,22.55545],[114.18979,22.55446],[114.1955,22.55564],[114.19674,22.55691],[114.20005,22.55717],[114.20376,22.55623],[114.20884,22.55672],[114.22438,22.55055],[114.2264,22.5476],[114.22545,22.54528],[114.22661,22.54339],[114.32,22.576],[114.45,22.43],[114.45,22.14],[113.9,22.14],[113.75,22.22],[113.553,22.095],[113.54678,22.1207],[113.5456,22.1207],[113.54076,22.12373],[113.54016,22.13618],[113.54701,22.13651],[113.5475,22.14583],[113.52456,22.17978],[113.53623,22.20191],[113.53299,22.21232],[113.53497,22.21351],[113.53735,22.21377],[113.54156,22.21315],[113.54385,22.21709],[113.55849,22.21565],[113.573,22.186]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-75,18],[-80,20.5],[-83,19],[-77,16],[-75,18]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-64.33594,32.86113],[-79.39819,27.21067],[-80.63965,23.71998],[-73.39966,20.40642],[-65.1709,19.20743],[-65.09399,16.23577],[-59.13391,16.80454],[-62.64404,15.16228],[-59.43054,14.85985],[-62.83081,13.64599],[-61.80359,10.73752],[-62.08649,10.04729],[-61.06201,9.85522],[-59.81369,8.31274],[-59.8027,8.27469],[-59.83498,8.22712],[-59.94141,8.21149],[-59.99771,8.15576],[-59.97986,8.13265],[-59.99771,8.12041],[-60.00183,8.07147],[-60.05127,8.02524],[-60.09933,8.03747],[-60.12268,8.02388],[-60.14053,7.98988],[-60.36163,7.83345],[-60.53467,7.81713],[-60.5896,7.6375],[-60.72144,7.54493],[-60.5896,7.31888],[-60.63904,7.24532],[-60.54703,7.12542],[-60.46875,7.20309],[-60.37262,7.18401],[-60.29984,7.1445],[-60.2916,7.06819],[-60.39871,6.95097],[-60.66513,6.83235],[-60.71869,6.75053],[-60.91232,6.81735],[-60.94254,6.72053],[-61.14441,6.72326],[-61.23093,6.5773],[-61.1554,6.45314],[-61.14441,6.20199],[-61.39709,5.95619],[-60.71045,5.20036],[-60.21606,5.23319],[-59.99634,5.06906],[-60.13916,4.51071],[-59.69971,4.40118],[-59.5459,3.93002],[-59.87549,3.56825],[-59.7876,3.37086],[-60.01831,2.83332],[-59.90845,2.38335],[-59.69971,2.2626],[-59.77661,1.87833],[-59.65302,1.85087],[-59.69147,1.75754],[-59.61456,1.71361],[-59.55139,1.73283],[-59.36188,1.49123],[-59.26575,1.39238],[-58.92242,1.30726],[-58.83728,1.17271],[-58.71918,1.23037],[-58.71094,1.29902],[-58.49121,1.26058],[-58.461,1.37591],[-58.50494,1.38689],[-58.51044,1.46102],[-58.38135,1.4775],[-58.32642,1.57359],[-58.00507,1.49946],[-57.99133,1.65321],[-57.79907,1.69165],[-57.70844,1.71087],[-57.54364,1.68341],[-57.41455,1.94421],[-57.10693,1.97715],[-56.8103,1.85636],[-56.48071,1.92225],[-55.90942,1.81244],[-55.90942,2.04302],[-56.14014,2.26534],[-55.94788,2.53701],[-55.70892,2.39981],[-55.37933,2.43274],[-55.19257,2.53976],[-54.98108,2.57268],[-54.88495,2.43548],[-54.71191,2.46293],[-54.69543,2.34767],[-54.58832,2.32846],[-54.43451,2.43548],[-54.20654,2.76748],[-54.17358,3.12955],[-53.96484,3.57921],[-54.33838,4.00674],[-54.44412,4.52577],[-54.46884,4.91036],[-54.36653,5.13061],[-54.27727,5.26191],[-54.19968,5.3084],[-54.01222,5.54457],[-54.0239,5.64605],[-53.86322,5.94936],[-64.33594,32.86113]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-14.5,-6],[11.79657,-17.27197],[12.03415,-17.14866],[12.38159,-17.22213],[12.58484,-17.22476],[13.01193,-16.97405],[13.24951,-17.00098],[13.38135,-16.98522],[13.93341,-17.38734],[18.42476,-17.38996],[18.47763,-17.46857],[18.62663,-17.64599],[18.79211,-17.76177],[18.92944,-17.82061],[19.33044,-17.84806],[19.66278,-17.8644],[19.74792,-17.90557],[19.85161,-17.87486],[20.10361,-17.90296],[20.18394,-17.88401],[20.34737,-17.88466],[20.44693,-17.91733],[20.51697,-17.96698],[20.83008,-18.03032],[20.95711,-17.97285],[21.16997,-17.93497],[21.42677,-18.0264],[23.45032,-17.63879],[22.00012,-16.38866],[21.99944,-13.00523],[24.03809,-12.99118],[24.03809,-10.91962],[24.43359,-11.09217],[24.45557,-11.48002],[25.37842,-11.19996],[25.42236,-11.60919],[26.96045,-11.97484],[27.18018,-11.60919],[28.125,-12.42048],[29.11377,-13.36824],[29.1687,-13.43771],[29.55872,-13.19716],[29.68506,-13.2239],[29.62463,-13.41099],[29.80591,-13.44305],[29.81415,-12.14809],[29.31152,-12.55456],[28.41064,-11.78133],[28.63037,-10.70379],[28.65234,-9.73071],[28.37219,-9.24309],[28.89748,-8.47916],[30.78644,-8.26857],[29.39941,-6.05316],[29.4873,-4.45595],[29.75922,-4.46759],[29.81415,-4.36421],[29.88007,-4.36832],[30.04074,-4.26699],[30.07919,-4.1629],[30.18356,-4.08311],[30.1918,-4.05126],[30.21566,-4.04595],[30.22923,-4.01136],[30.21326,-3.99612],[30.25978,-3.88755],[30.29274,-3.86288],[30.34424,-3.77245],[30.39848,-3.79095],[30.40878,-3.76765],[30.39548,-3.7304],[30.39054,-3.72821],[30.3896,-3.71918],[30.39093,-3.7101],[30.39514,-3.70444],[30.42028,-3.64963],[30.46886,-3.53501],[30.67108,-3.41335],[30.63297,-3.34892],[30.84206,-3.25535],[30.84549,-3.16108],[30.83485,-3.09698],[30.7933,-3.06235],[30.82111,-3.02258],[30.84515,-2.9739],[30.74764,-2.99618],[30.7037,-2.97013],[30.66422,-2.98967],[30.57632,-2.90738],[30.49393,-2.94441],[30.41016,-2.87172],[30.52002,-2.39432],[30.77545,-2.38883],[30.8606,-2.31199],[30.84961,-2.19398],[30.89081,-2.07322],[30.81116,-1.96068],[30.83862,-1.6587],[30.73425,-1.4418],[30.56259,-1.33884],[30.4541,-1.05737],[30.35797,-1.06287],[30.34149,-1.13152],[30.16571,-1.34296],[29.91852,-1.48024],[29.83887,-1.31824],[29.58344,-1.39238],[29.729,0.05493],[29.96796,0.5136],[29.9707,0.8569],[30.22339,0.92281],[30.24536,1.15349],[30.47745,1.20772],[31.30966,2.15693],[31.20255,2.22211],[31.20255,2.29278],[31.16409,2.27906],[31.13937,2.28318],[31.13113,2.26534],[31.07826,2.30033],[31.0714,2.34767],[31.00479,2.4005],[30.97183,2.40461],[30.94711,2.38746],[30.94849,2.36276],[30.9375,2.33532],[30.88531,2.34012],[30.83038,2.42176],[30.74112,2.43274],[30.76035,2.5864],[30.90179,2.88132],[30.76447,3.04178],[30.93613,3.40239],[30.94059,3.50588],[30.85236,3.48601],[30.90866,3.5936],[30.95055,3.63918],[30.94677,3.65391],[30.9866,3.70187],[31.00582,3.70701],[31.02058,3.69708],[31.16547,3.7954],[31.28838,3.79643],[31.52699,3.66282],[31.7038,3.72449],[31.82671,3.82794],[31.96198,3.65596],[31.95854,3.57099],[32.04987,3.59155],[32.07733,3.57099],[32.0842,3.53672],[32.20093,3.50657],[32.21672,3.56448],[32.19578,3.59977],[32.41516,3.74504],[32.72055,3.76782],[32.89307,3.81219],[33.02782,3.89371],[33.18146,3.7793],[33.51173,3.75258],[33.98758,4.23309],[34.05762,4.28342],[34.38721,4.61065],[35.94452,4.62023],[35.95688,4.53467],[36.04134,4.44568],[36.89621,4.4491],[38.14728,3.62992],[38.55927,3.62033],[38.92181,3.51068],[39.56039,3.43392],[39.87076,3.87522],[40.76752,4.28753],[41.16371,3.94372],[41.89774,3.97797],[41.31271,3.14463],[40.98896,2.82869],[40.99548,-0.84042],[41.7,-1.8],[41.7,-49],[-27,-60],[-65.7,-52.5],[-14.5,-6]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[31.33301,35.47856],[33.0249,33.75175],[35.44189,36.02245],[31.33301,35.47856]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[14,36.5],[15,36],[14,35],[14,36.5]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[0,62],[2.5,51.3],[-2,50],[-1.9,49],[-20,53],[0,62]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[180,-35],[161,-19],[167,-12],[180,-22],[180,4],[170,3.7],[127,5.7],[118,2.7],[119.5,5.4],[117.2,7.5],[102.6,8],[102.9158,11.74099],[102.76268,12.07357],[102.70226,12.17158],[102.74139,12.46474],[102.53128,12.68857],[102.49557,12.9256],[102.49763,13.0064],[102.4597,13.08199],[102.43412,13.09026],[102.39155,13.16407],[102.35481,13.29341],[102.35893,13.30945],[102.34503,13.34837],[102.35928,13.39797],[102.3567,13.48095],[102.36168,13.50582],[102.33559,13.53787],[102.33971,13.56023],[102.35498,13.5649],[102.36511,13.5785],[102.40047,13.5679],[102.42537,13.56891],[102.44614,13.56123],[102.48047,13.57091],[102.53849,13.56757],[102.5699,13.58526],[102.57806,13.60486],[102.62501,13.60845],[102.62132,13.61295],[102.60767,13.61562],[102.57231,13.63331],[102.56922,13.64082],[102.54879,13.658],[102.56252,13.68552],[102.5972,13.70803],[102.67084,13.74472],[102.68818,13.75172],[102.7014,13.7684],[102.73161,13.77082],[102.76543,13.85541],[102.78397,13.93207],[102.80388,13.94406],[102.81607,13.96639],[102.90705,14.02119],[102.89726,14.0535],[102.90095,14.0838],[102.92421,14.10744],[102.92378,14.12838],[102.94147,14.15035],[102.92953,14.17952],[103.17535,14.33774],[103.19939,14.32992],[103.68553,14.44],[103.94508,14.34157],[104.05756,14.34589],[104.06636,14.3419],[104.26025,14.37749],[104.50058,14.36984],[104.57817,14.36019],[104.6422,14.42387],[104.66632,14.40234],[104.68357,14.39877],[104.71138,14.43169],[104.72305,14.42188],[104.71687,14.40043],[104.75344,14.40459],[104.80408,14.43867],[104.83429,14.41573],[104.99239,14.3838],[105.05402,14.19783],[105.47905,14.49186],[105.60883,15.0005],[105.46703,15.13005],[105.48866,15.20237],[105.59269,15.2716],[105.58617,15.32823],[105.50308,15.31912],[105.46703,15.33948],[105.49175,15.37921],[105.59372,15.42869],[105.59372,15.50927],[105.60986,15.54871],[105.62616,15.56492],[105.62702,15.59129],[105.63518,15.62742],[105.63612,15.66056],[105.5975,15.72088],[105.49965,15.76681],[105.46291,15.74517],[105.43819,15.75459],[105.40489,15.79424],[105.34241,15.92039],[105.37811,15.98344],[105.39167,15.99136],[105.41931,15.98608],[105.42652,15.99764],[105.41468,16.01661],[105.21263,16.05076],[105.04955,16.10552],[105.01316,16.24401],[104.88235,16.37812],[104.8391,16.45782],[104.77936,16.49041],[104.73919,16.53287],[104.74228,16.62205],[104.76391,16.70953],[104.73953,16.80323],[104.76425,16.85088],[104.73782,16.90968],[104.744,17.0128],[104.81266,17.21853],[104.79841,17.39274],[104.70348,17.52833],[104.46384,17.65515],[104.34368,17.83564],[104.27776,17.8559],[104.22661,17.98069],[104.1116,18.10735],[104.06525,18.21174],[103.97392,18.33823],[103.9286,18.33237],[103.88809,18.29456],[103.85582,18.28673],[103.83659,18.32715],[103.79128,18.3467],[103.70201,18.34214],[103.60931,18.40405],[103.57292,18.40437],[103.51593,18.42978],[103.45963,18.42587],[103.41568,18.44802],[103.30479,18.43206],[103.24265,18.37082],[103.24333,18.34133],[103.29123,18.32357],[103.28899,18.29521],[103.23595,18.28299],[103.16608,18.25511],[103.02429,17.98135],[102.6535,17.83237],[102.40631,17.99963],[102.10968,18.22413],[101.548,17.81538],[101.30493,17.64991],[101.14563,17.46595],[100.95886,17.61654],[101.01757,17.88858],[101.18752,18.05121],[101.16863,18.10409],[101.18134,18.33595],[101.08727,18.38287],[101.05499,18.43988],[101.23215,18.73015],[101.35265,19.04524],[101.25927,19.12733],[101.2373,19.32637],[101.25824,19.58438],[101.11954,19.56836],[101.08898,19.58777],[101.08624,19.59715],[101.03165,19.6185],[100.89844,19.62125],[100.77827,19.49249],[100.63751,19.56432],[100.58258,19.49313],[100.47478,19.5944],[100.42929,19.67152],[100.43341,19.7024],[100.4147,19.7255],[100.40525,19.7646],[100.43907,19.80345],[100.45555,19.84843],[100.50636,19.87264],[100.51709,19.93027],[100.58653,20.1599],[100.56576,20.1757],[100.54945,20.17473],[100.52731,20.14379],[100.51065,20.14895],[100.48697,20.17956],[100.46774,20.196],[100.45246,20.20147],[100.45521,20.22129],[100.44783,20.23546],[100.41607,20.25286],[100.40594,20.28184],[100.38397,20.31082],[100.37556,20.35187],[100.36165,20.35638],[100.35736,20.37408],[100.33195,20.39902],[100.27805,20.40224],[100.25917,20.39677],[100.2475,20.37263],[100.22535,20.35509],[100.22346,20.31839],[100.16579,20.29988],[100.17162,20.24545],[100.10845,20.25221],[100.09266,20.2696],[100.09798,20.31485],[100.07961,20.3678],[99.9567,20.46417],[99.91636,20.44925],[99.90765,20.44977],[99.89121,20.44511],[99.87276,20.44406],[99.86212,20.44326],[99.80186,20.33948],[99.46472,20.3884],[99.56085,20.20035],[99.43691,20.08882],[99.27727,20.11623],[99.06921,20.1101],[98.97789,19.74538],[98.24387,19.68656],[97.85934,19.57014],[97.76733,18.57336],[97.39655,18.47179],[97.62451,18.30238],[97.73849,17.97743],[97.66502,17.87943],[97.90947,17.56745],[98.52951,16.82557],[98.51303,16.69276],[98.69293,16.26873],[98.87421,16.43609],[98.93394,16.3353],[98.84743,16.13356],[98.74512,16.12037],[98.58307,16.07287],[98.5762,15.79754],[98.54736,15.37557],[98.17383,15.15167],[98.3606,14.63674],[99.08295,13.89208],[99.16534,13.72204],[99.18182,13.00723],[99.39331,12.56797],[99.64153,11.78973],[99.32156,11.30266],[98.77859,10.67849],[98.80597,10.47642],[98.76657,10.40459],[98.74924,10.34194],[96.85547,6.40265],[92.42523,20.54794],[92.2728,20.96272],[92.187,21.16],[92.26,21.36],[92.27,21.4328],[92.62,21.43],[92.6,22],[93.22,22.25],[93.4,23.7],[93.34,23.95],[94.155,23.847],[94.17,23.92],[94.25171,24.07405],[94.28,24.23],[94.30175,24.2371],[94.3256,24.2731],[94.6,24.7],[94.78,25.47],[95.2,26],[95.1,26.6],[97.3,27.9],[96.14,29.38],[95.4,29.1],[94.8,29.2],[92.5,27.8],[91.64,27.76],[91.4,28],[89.58,28.18],[88.9,27.32],[88.74,27.47],[88.9,27.86],[88.7,28.1],[88.1,27.87],[85.93,27.942],[81.6,30.5],[81.2,30],[78.73,31.5],[78.77,31.99],[78.4,32.5],[79.3,32.5],[79,34.3],[78.3,34.6],[78,35.5],[76.1,35.8],[76,36.55],[75.15,37],[72.5,36.9],[71.1,36.1],[71.65,35.44],[71.45,35],[70.985,34.54],[71.18,34.36],[71.092,34.118],[70.88,33.97],[70.5,33.94],[69.908,34.04],[69.869,33.96],[70,33.75],[70.13,33.73],[70.34,33.34],[70.013,33.14],[69.57,33.09],[69.24,32.45],[69.3,31.9],[68.1,31.6],[66.393,30.934],[66.2,29.8],[62.5,29.4],[60.87,29.86],[61.53,29.0165],[61.66,28.77],[61.96,28.54],[62.43,28.42],[62.6,28.25],[62.795,28.28],[62.86,27.25],[63.24,27.25],[63.327,27.13],[63.25,27.1],[63.25,26.84],[63.18,26.83],[63.18,26.65],[62.3,26.5],[62.2,26.28],[61.85,26.22],[61.84,25.75],[61.68,25.67],[56.5,-21],[180,-65],[180,-35]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[138.7,46.7],[145.5,44.5],[145.2,43.7],[146,43.3],[142,18],[122,24.3],[138.7,46.7]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-180,7],[-148,7],[-151,-12],[-171.5,-10.75],[-171,-16],[-152,-19],[-180,-55],[-180,7]]]}}];
18953 var dataDriveLeft = {
18955 features: features$1
18958 var en = {"modes":{"add_area":{"title":"Area","description":"Add parks, buildings, lakes or other areas to the map.","tail":"Click on the map to start drawing an area, like a park, lake, or building."},"add_line":{"title":"Line","description":"Add highways, streets, pedestrian paths, canals or other lines to the map.","tail":"Click on the map to start drawing a road, path, or route."},"add_point":{"title":"Point","description":"Add restaurants, monuments, postal boxes or other points to the map.","tail":"Click on the map to add a point."},"browse":{"title":"Browse","description":"Pan and zoom the map."},"draw_area":{"tail":"Click to add nodes to your area. Click the first node to finish the area."},"draw_line":{"tail":"Click to add more nodes to the line. Click on other lines to connect to them, and double-click to end the line."}},"operations":{"add":{"annotation":{"point":"Added a point.","vertex":"Added a node to a way.","relation":"Added a relation."}},"start":{"annotation":{"line":"Started a line.","area":"Started an area."}},"continue":{"key":"A","title":"Continue","description":"Continue this line.","not_eligible":"No line can be continued here.","multiple":"Several lines can be continued here. To choose a line, press the Shift key and click on it to select it.","annotation":{"line":"Continued a line.","area":"Continued an area."}},"cancel_draw":{"annotation":"Canceled drawing."},"change_role":{"annotation":"Changed the role of a relation member."},"change_tags":{"annotation":"Changed tags."},"circularize":{"title":"Circularize","description":{"line":"Make this line circular.","area":"Make this area circular."},"key":"O","annotation":{"line":"Made a line circular.","area":"Made an area circular."},"not_closed":"This can't be made circular because it's not a loop.","too_large":"This can't be made circular because not enough of it is currently visible.","connected_to_hidden":"This can't be made circular because it is connected to a hidden feature."},"orthogonalize":{"title":"Square","description":{"line":"Square the corners of this line.","area":"Square the corners of this area."},"key":"S","annotation":{"line":"Squared the corners of a line.","area":"Squared the corners of an area."},"not_squarish":"This can't be made square because it is not squarish.","too_large":"This can't be made square because not enough of it is currently visible.","connected_to_hidden":"This can't be made square because it is connected to a hidden feature."},"straighten":{"title":"Straighten","description":"Straighten this line.","key":"S","annotation":"Straightened a line.","too_bendy":"This can't be straightened because it bends too much.","connected_to_hidden":"This line can't be straightened because it is connected to a hidden feature."},"delete":{"title":"Delete","description":"Delete object permanently.","annotation":{"point":"Deleted a point.","vertex":"Deleted a node from a way.","line":"Deleted a line.","area":"Deleted an area.","relation":"Deleted a relation.","multiple":"Deleted {n} objects."},"incomplete_relation":"This feature can't be deleted because it hasn't been fully downloaded.","part_of_relation":"This feature can't be deleted because it's part of a larger relation. You must remove it from the relation first.","connected_to_hidden":"This can't be deleted because it is connected to a hidden feature."},"add_member":{"annotation":"Added a member to a relation."},"delete_member":{"annotation":"Removed a member from a relation."},"connect":{"annotation":{"point":"Connected a way to a point.","vertex":"Connected a way to another.","line":"Connected a way to a line.","area":"Connected a way to an area."}},"disconnect":{"title":"Disconnect","description":"Disconnect these lines/areas from each other.","key":"D","annotation":"Disconnected lines/areas.","not_connected":"There aren't enough lines/areas here to disconnect.","connected_to_hidden":"This can't be disconnected because it is connected to a hidden feature.","relation":"This can't be disconnected because it connects members of a relation."},"merge":{"title":"Merge","description":"Merge these features.","key":"C","annotation":"Merged {n} features.","not_eligible":"These features can't be merged.","not_adjacent":"These features can't be merged because they aren't connected.","restriction":"These features can't be merged because at least one is a member of a \"{relation}\" relation.","incomplete_relation":"These features can't be merged because at least one hasn't been fully downloaded.","conflicting_tags":"These features can't be merged because some of their tags have conflicting values."},"move":{"title":"Move","description":"Move this to a different location.","key":"M","annotation":{"point":"Moved a point.","vertex":"Moved a node in a way.","line":"Moved a line.","area":"Moved an area.","multiple":"Moved multiple objects."},"incomplete_relation":"This feature can't be moved because it hasn't been fully downloaded.","too_large":"This can't be moved because not enough of it is currently visible.","connected_to_hidden":"This can't be moved because it is connected to a hidden feature."},"rotate":{"title":"Rotate","description":"Rotate this object around its center point.","key":"R","annotation":{"line":"Rotated a line.","area":"Rotated an area."},"too_large":"This can't be rotated because not enough of it is currently visible.","connected_to_hidden":"This can't be rotated because it is connected to a hidden feature."},"reverse":{"title":"Reverse","description":"Make this line go in the opposite direction.","key":"V","annotation":"Reversed a line."},"split":{"title":"Split","description":{"line":"Split this line into two at this node.","area":"Split the boundary of this area into two.","multiple":"Split the lines/area boundaries at this node into two."},"key":"X","annotation":{"line":"Split a line.","area":"Split an area boundary.","multiple":"Split {n} lines/area boundaries."},"not_eligible":"Lines can't be split at their beginning or end.","multiple_ways":"There are too many lines here to split.","connected_to_hidden":"This can't be split because it is connected to a hidden feature."},"restriction":{"help":{"select":"Click to select a road segment.","toggle":"Click to toggle turn restrictions.","toggle_on":"Click to add a \"{restriction}\" restriction.","toggle_off":"Click to remove the \"{restriction}\" restriction."},"annotation":{"create":"Added a turn restriction","delete":"Deleted a turn restriction"}}},"undo":{"tooltip":"Undo: {action}","nothing":"Nothing to undo."},"redo":{"tooltip":"Redo: {action}","nothing":"Nothing to redo."},"tooltip_keyhint":"Shortcut:","browser_notice":"This editor is supported in Firefox, Chrome, Safari, Opera, and Internet Explorer 11 and above. Please upgrade your browser or use Potlatch 2 to edit the map.","translate":{"translate":"Translate","localized_translation_label":"Multilingual name","localized_translation_language":"Choose language","localized_translation_name":"Name"},"zoom_in_edit":"Zoom in to Edit","login":"login","logout":"logout","loading_auth":"Connecting to OpenStreetMap...","report_a_bug":"Report a bug","help_translate":"Help translate","feature_info":{"hidden_warning":"{count} hidden features","hidden_details":"These features are currently hidden: {details}"},"status":{"error":"Unable to connect to API.","offline":"The API is offline. Please try editing later.","readonly":"The API is read-only. You will need to wait to save your changes.","rateLimit":"The API is limiting anonymous connections. You can fix this by logging in."},"commit":{"title":"Save Changes","description_placeholder":"Brief description of your contributions (required)","message_label":"Changeset comment","upload_explanation":"The changes you upload will be visible on all maps that use OpenStreetMap data.","upload_explanation_with_user":"The changes you upload as {user} will be visible on all maps that use OpenStreetMap data.","save":"Save","cancel":"Cancel","changes":"{count} Changes","warnings":"Warnings","modified":"Modified","deleted":"Deleted","created":"Created","about_changeset_comments":"About changeset comments","about_changeset_comments_link":"//wiki.openstreetmap.org/wiki/Good_changeset_comments","google_warning":"You mentioned Google in this comment: remember that copying from Google Maps is strictly forbidden.","google_warning_link":"http://www.openstreetmap.org/copyright"},"contributors":{"list":"Edits by {users}","truncated_list":"Edits by {users} and {count} others"},"infobox":{"selected":"{n} selected","geometry":"Geometry","closed":"closed","center":"Center","perimeter":"Perimeter","length":"Length","area":"Area","centroid":"Centroid","location":"Location","metric":"Metric","imperial":"Imperial"},"geometry":{"point":"point","vertex":"vertex","line":"line","area":"area","relation":"relation"},"geocoder":{"search":"Search worldwide...","no_results_visible":"No results in visible map area","no_results_worldwide":"No results found"},"geolocate":{"title":"Show My Location","locating":"Locating, please wait..."},"inspector":{"no_documentation_combination":"There is no documentation available for this tag combination","no_documentation_key":"There is no documentation available for this key","documentation_redirect":"This documentation has been redirected to a new page","show_more":"Show More","view_on_osm":"View on openstreetmap.org","all_fields":"All fields","all_tags":"All tags","all_members":"All members","all_relations":"All relations","new_relation":"New relation...","role":"Role","choose":"Select feature type","results":"{n} results for {search}","reference":"View on OpenStreetMap Wiki","back_tooltip":"Change feature","remove":"Remove","search":"Search","multiselect":"Selected items","unknown":"Unknown","incomplete":"<not downloaded>","feature_list":"Search features","edit":"Edit feature","check":{"yes":"Yes","no":"No"},"add":"Add","none":"None","node":"Node","way":"Way","relation":"Relation","location":"Location","add_fields":"Add field:"},"background":{"title":"Background","description":"Background settings","percent_brightness":"{opacity}% brightness","none":"None","best_imagery":"Best known imagery source for this location","switch":"Switch back to this background","custom":"Custom","custom_button":"Edit custom background","custom_prompt":"Enter a tile URL template. Valid tokens are {zoom}, {x}, {y} for Z/X/Y scheme and {u} for quadtile scheme.","fix_misalignment":"Adjust imagery offset","imagery_source_faq":"Where does this imagery come from?","reset":"reset","offset":"Drag anywhere in the gray area below to adjust the imagery offset, or enter the offset values in meters.","minimap":{"description":"Minimap","tooltip":"Show a zoomed out map to help locate the area currently displayed."}},"map_data":{"title":"Map Data","description":"Map Data","data_layers":"Data Layers","fill_area":"Fill Areas","map_features":"Map Features","autohidden":"These features have been automatically hidden because too many would be shown on the screen. You can zoom in to edit them."},"feature":{"points":{"description":"Points","tooltip":"Points of Interest"},"traffic_roads":{"description":"Traffic Roads","tooltip":"Highways, Streets, etc."},"service_roads":{"description":"Service Roads","tooltip":"Service Roads, Parking Aisles, Tracks, etc."},"paths":{"description":"Paths","tooltip":"Sidewalks, Foot Paths, Cycle Paths, etc."},"buildings":{"description":"Buildings","tooltip":"Buildings, Shelters, Garages, etc."},"landuse":{"description":"Landuse Features","tooltip":"Forests, Farmland, Parks, Residential, Commercial, etc."},"boundaries":{"description":"Boundaries","tooltip":"Administrative Boundaries"},"water":{"description":"Water Features","tooltip":"Rivers, Lakes, Ponds, Basins, etc."},"rail":{"description":"Rail Features","tooltip":"Railways"},"power":{"description":"Power Features","tooltip":"Power Lines, Power Plants, Substations, etc."},"past_future":{"description":"Past/Future","tooltip":"Proposed, Construction, Abandoned, Demolished, etc."},"others":{"description":"Others","tooltip":"Everything Else"}},"area_fill":{"wireframe":{"description":"No Fill (Wireframe)","tooltip":"Enabling wireframe mode makes it easy to see the background imagery."},"partial":{"description":"Partial Fill","tooltip":"Areas are drawn with fill only around their inner edges. (Recommended for beginner mappers)"},"full":{"description":"Full Fill","tooltip":"Areas are drawn fully filled."}},"restore":{"heading":"You have unsaved changes","description":"Do you wish to restore unsaved changes from a previous editing session?","restore":"Restore","reset":"Reset"},"save":{"title":"Save","help":"Save changes to OpenStreetMap, making them visible to other users.","no_changes":"No changes to save.","error":"Errors occurred while trying to save","status_code":"Server returned status code {code}","unknown_error_details":"Please ensure you are connected to the internet.","uploading":"Uploading changes to OpenStreetMap.","unsaved_changes":"You have unsaved changes","conflict":{"header":"Resolve conflicting edits","count":"Conflict {num} of {total}","previous":"< Previous","next":"Next >","keep_local":"Keep mine","keep_remote":"Use theirs","restore":"Restore","delete":"Leave Deleted","download_changes":"Or download your changes.","done":"All conflicts resolved!","help":"Another user changed some of the same map features you changed.\nClick on each item below for more details about the conflict, and choose whether to keep\nyour changes or the other user's changes.\n"}},"merge_remote_changes":{"conflict":{"deleted":"This object has been deleted by {user}.","location":"This object was moved by both you and {user}.","nodelist":"Nodes were changed by both you and {user}.","memberlist":"Relation members were changed by both you and {user}.","tags":"You changed the <b>{tag}</b> tag to \"{local}\" and {user} changed it to \"{remote}\"."}},"success":{"edited_osm":"Edited OSM!","just_edited":"You just edited OpenStreetMap!","view_on_osm":"View on OSM","facebook":"Share on Facebook","twitter":"Share on Twitter","google":"Share on Google+","help_html":"Your changes should appear in the \"Standard\" layer in a few minutes. Other layers, and certain features, may take longer.","help_link_text":"Details","help_link_url":"https://wiki.openstreetmap.org/wiki/FAQ#I_have_just_made_some_changes_to_the_map._How_do_I_get_to_see_my_changes.3F"},"confirm":{"okay":"Okay","cancel":"Cancel"},"splash":{"welcome":"Welcome to the iD OpenStreetMap editor","text":"iD is a friendly but powerful tool for contributing to the world's best free world map. This is version {version}. For more information see {website} and report bugs at {github}.","walkthrough":"Start the Walkthrough","start":"Edit Now"},"source_switch":{"live":"live","lose_changes":"You have unsaved changes. Switching the map server will discard them. Are you sure you want to switch servers?","dev":"dev"},"tag_reference":{"description":"Description","on_wiki":"{tag} on wiki.osm.org","used_with":"used with {type}"},"validations":{"untagged_point":"Untagged point","untagged_line":"Untagged line","untagged_area":"Untagged area","many_deletions":"You're deleting {n} objects. Are you sure you want to do this? This will delete them from the map that everyone else sees on openstreetmap.org.","tag_suggests_area":"The tag {tag} suggests line should be area, but it is not an area","untagged_point_tooltip":"Select a feature type that describes what this point is.","untagged_line_tooltip":"Select a feature type that describes what this line is.","untagged_area_tooltip":"Select a feature type that describes what this area is.","deprecated_tags":"Deprecated tags: {tags}"},"zoom":{"in":"Zoom In","out":"Zoom Out"},"cannot_zoom":"Cannot zoom out further in current mode.","full_screen":"Toggle Full Screen","gpx":{"local_layer":"Local GPX file","drag_drop":"Drag and drop a .gpx file on the page, or click the button to the right to browse","zoom":"Zoom to GPX track","browse":"Browse for a .gpx file"},"mapillary_images":{"tooltip":"Street-level photos from Mapillary","title":"Photo Overlay (Mapillary)"},"mapillary_signs":{"tooltip":"Traffic signs from Mapillary (must enable Photo Overlay)","title":"Traffic Sign Overlay (Mapillary)"},"mapillary":{"view_on_mapillary":"View this image on Mapillary"},"help":{"title":"Help","help":"# Help\n\nThis is an editor for [OpenStreetMap](http://www.openstreetmap.org/), the\nfree and editable map of the world. You can use it to add and update\ndata in your area, making an open-source and open-data map of the world\nbetter for everyone.\n\nEdits that you make on this map will be visible to everyone who uses\nOpenStreetMap. In order to make an edit, you'll need to\n[log in](https://www.openstreetmap.org/login).\n\nThe [iD editor](http://ideditor.com/) is a collaborative project with [source\ncode available on GitHub](https://github.com/openstreetmap/iD).\n","editing_saving":"# Editing & Saving\n\nThis editor is designed to work primarily online, and you're accessing\nit through a website right now.\n\n### Selecting Features\n\nTo select a map feature, like a road or point of interest, click\non it on the map. This will highlight the selected feature, open a panel with\ndetails about it, and show a menu of things you can do with the feature.\n\nTo select multiple features, hold down the 'Shift' key. Then either click\non the features you want to select, or drag on the map to draw a rectangle.\nThis will draw a box and select all the points within it.\n\n### Saving Edits\n\nWhen you make changes like editing roads, buildings, and places, these are\nstored locally until you save them to the server. Don't worry if you make\na mistake - you can undo changes by clicking the undo button, and redo\nchanges by clicking the redo button.\n\nClick 'Save' to finish a group of edits - for instance, if you've completed\nan area of town and would like to start on a new area. You'll have a chance\nto review what you've done, and the editor supplies helpful suggestions\nand warnings if something doesn't seem right about the changes.\n\nIf everything looks good, you can enter a short comment explaining the change\nyou made, and click 'Save' again to post the changes\nto [OpenStreetMap.org](http://www.openstreetmap.org/), where they are visible\nto all other users and available for others to build and improve upon.\n\nIf you can't finish your edits in one sitting, you can leave the editor\nwindow and come back (on the same browser and computer), and the\neditor application will offer to restore your work.\n\n### Using the editor\n\nA list of available keyboard shortcuts can be found [here](http://wiki.openstreetmap.org/wiki/ID/Shortcuts).\n","roads":"# Roads\n\nYou can create, fix, and delete roads with this editor. Roads can be all\nkinds: paths, highways, trails, cycleways, and more - any often-crossed\nsegment should be mappable.\n\n### Selecting\n\nClick on a road to select it. An outline should become visible, along\nwith a small tools menu on the map and a sidebar showing more information\nabout the road.\n\n### Modifying\n\nOften you'll see roads that aren't aligned to the imagery behind them\nor to a GPS track. You can adjust these roads so they are in the correct\nplace.\n\nFirst click on the road you want to change. This will highlight it and show\ncontrol points along it that you can drag to better locations. If\nyou want to add new control points for more detail, double-click a part\nof the road without a node, and one will be added.\n\nIf the road connects to another road, but doesn't properly connect on\nthe map, you can drag one of its control points onto the other road in\norder to join them. Having roads connect is important for the map\nand essential for providing driving directions.\n\nYou can also click the 'Move' tool or press the `M` shortcut key to move the entire road at\none time, and then click again to save that movement.\n\n### Deleting\n\nIf a road is entirely incorrect - you can see that it doesn't exist in satellite\nimagery and ideally have confirmed locally that it's not present - you can delete\nit, which removes it from the map. Be cautious when deleting features -\nlike any other edit, the results are seen by everyone and satellite imagery\nis often out of date, so the road could simply be newly built.\n\nYou can delete a road by clicking on it to select it, then clicking the\ntrash can icon or pressing the 'Delete' key.\n\n### Creating\n\nFound somewhere there should be a road but there isn't? Click the 'Line'\nicon in the top-left of the editor or press the shortcut key `2` to start drawing\na line.\n\nClick on the start of the road on the map to start drawing. If the road\nbranches off from an existing road, start by clicking on the place where they connect.\n\nThen click on points along the road so that it follows the right path, according\nto satellite imagery or GPS. If the road you are drawing crosses another road, connect\nit by clicking on the intersection point. When you're done drawing, double-click\nor press 'Return' or 'Enter' on your keyboard.\n","gps":"# GPS\n\nCollected GPS traces are one valuable source of data for OpenStreetMap. This editor\nsupports local traces - `.gpx` files on your local computer. You can collect\nthis kind of GPS trace with a number of smartphone applications as well as\npersonal GPS hardware.\n\nFor information on how to perform a GPS survey, read\n[Mapping with a smartphone, GPS, or paper](http://learnosm.org/en/mobile-mapping/).\n\nTo use a GPX track for mapping, drag and drop the GPX file onto the map\neditor. If it's recognized, it will be added to the map as a bright purple\nline. Click on the 'Map Data' menu on the right side to enable,\ndisable, or zoom to this new GPX-powered layer.\n\nThe GPX track isn't directly uploaded to OpenStreetMap - the best way to\nuse it is to draw on the map, using it as a guide for the new features that\nyou add, and also to [upload it to OpenStreetMap](http://www.openstreetmap.org/trace/create)\nfor other users to use.\n","imagery":"# Imagery\n\nAerial imagery is an important resource for mapping. A combination of\nairplane flyovers, satellite views, and freely-compiled sources are available\nin the editor under the 'Background Settings' menu on the right.\n\nBy default a [Bing Maps](http://www.bing.com/maps/) satellite layer is\npresented in the editor, but as you pan and zoom the map to new geographical\nareas, new sources will become available. Some countries, like the United\nStates, France, and Denmark have very high-quality imagery available for some areas.\n\nImagery is sometimes offset from the map data because of a mistake on the\nimagery provider's side. If you see a lot of roads shifted from the background,\ndon't immediately move them all to match the background. Instead you can adjust\nthe imagery so that it matches the existing data by clicking 'Fix alignment' at\nthe bottom of the Background Settings UI.\n","addresses":"# Addresses\n\nAddresses are some of the most useful information for the map.\n\nAlthough addresses are often represented as parts of streets, in OpenStreetMap\nthey're recorded as attributes of buildings and places along streets.\n\nYou can add address information to places mapped as building outlines\nas well as those mapped as single points. The optimal source of address\ndata is from an on-the-ground survey or personal knowledge - as with any\nother feature, copying from commercial sources like Google Maps is strictly\nforbidden.\n","inspector":"# Using the Inspector\n\nThe inspector is the section on the left side of the page that allows you to\nedit the details of the selected feature.\n\n### Selecting a Feature Type\n\nAfter you add a point, line, or area, you can choose what type of feature it\nis, like whether it's a highway or residential road, supermarket or cafe.\nThe inspector will display buttons for common feature types, and you can\nfind others by typing what you're looking for in the search box.\n\nClick the 'i' in the bottom-right-hand corner of a feature type button to\nlearn more about it. Click a button to choose that type.\n\n### Using Forms and Editing Tags\n\nAfter you choose a feature type, or when you select a feature that already\nhas a type assigned, the inspector will display fields with details about\nthe feature like its name and address.\n\nBelow the fields you see, you can click the 'Add field' dropdown to add\nother details, like a Wikipedia link, wheelchair access, and more.\n\nAt the bottom of the inspector, click 'Additional tags' to add arbitrary\nother tags to the element. [Taginfo](http://taginfo.openstreetmap.org/) is a\ngreat resource for learn more about popular tag combinations.\n\nChanges you make in the inspector are automatically applied to the map.\nYou can undo them at any time by clicking the 'Undo' button.\n","buildings":"# Buildings\n\nOpenStreetMap is the world's largest database of buildings. You can create\nand improve this database.\n\n### Selecting\n\nYou can select a building by clicking on its border. This will highlight the\nbuilding and open a small tools menu and a sidebar showing more information\nabout the building.\n\n### Modifying\n\nSometimes buildings are incorrectly placed or have incorrect tags.\n\nTo move an entire building, select it, then click the 'Move' tool. Move your\nmouse to shift the building, and click when it's correctly placed.\n\nTo fix the specific shape of a building, click and drag the nodes that form\nits border into better places.\n\n### Creating\n\nOne of the main questions around adding buildings to the map is that\nOpenStreetMap records buildings both as shapes and points. The rule of thumb\nis to _map a building as a shape whenever possible_, and map companies, homes,\namenities, and other things that operate out of buildings as points placed\nwithin the building shape.\n\nStart drawing a building as a shape by clicking the 'Area' button in the top\nleft of the interface, and end it either by pressing 'Return' on your keyboard\nor clicking on the first node drawn to close the shape.\n\n### Deleting\n\nIf a building is entirely incorrect - you can see that it doesn't exist in satellite\nimagery and ideally have confirmed locally that it's not present - you can delete\nit, which removes it from the map. Be cautious when deleting features -\nlike any other edit, the results are seen by everyone and satellite imagery\nis often out of date, so the building could simply be newly built.\n\nYou can delete a building by clicking on it to select it, then clicking the\ntrash can icon or pressing the 'Delete' key.\n","relations":"# Relations\n\nA relation is a special type of feature in OpenStreetMap that groups together\nother features. For example, two common types of relations are *route relations*,\nwhich group together sections of road that belong to a specific freeway or\nhighway, and *multipolygons*, which group together several lines that define\na complex area (one with several pieces or holes in it like a donut).\n\nThe group of features in a relation are called *members*. In the sidebar, you can\nsee which relations a feature is a member of, and click on a relation there\nto select the it. When the relation is selected, you can see all of its\nmembers listed in the sidebar and highlighted on the map.\n\nFor the most part, iD will take care of maintaining relations automatically\nwhile you edit. The main thing you should be aware of is that if you delete a\nsection of road to redraw it more accurately, you should make sure that the\nnew section is a member of the same relations as the original.\n\n## Editing Relations\n\nIf you want to edit relations, here are the basics.\n\nTo add a feature to a relation, select the feature, click the \"+\" button in the\n\"All relations\" section of the sidebar, and select or type the name of the relation.\n\nTo create a new relation, select the first feature that should be a member,\nclick the \"+\" button in the \"All relations\" section, and select \"New relation...\".\n\nTo remove a feature from a relation, select the feature and click the trash\nbutton next to the relation you want to remove it from.\n\nYou can create multipolygons with holes using the \"Merge\" tool. Draw two areas (inner\nand outer), hold the Shift key and click on each of them to select them both, and then\nclick the \"Merge\" (+) button.\n"},"intro":{"done":"done","graph":{"city_hall":"Three Rivers City Hall","fire_department":"Three Rivers Fire Department","memory_isle_park":"Memory Isle Park","riverwalk_trail":"Riverwalk Trail","w_michigan_ave":"West Michigan Avenue","e_michigan_ave":"East Michigan Avenue","spring_st":"Spring Street","scidmore_park":"Scidmore Park","petting_zoo":"Scidmore Park Petting Zoo","n_andrews_st":"North Andrews Street","s_andrews_st":"South Andrews Street","n_constantine_st":"North Constantine Street","s_constantine_st":"South Constantine Street","rocky_river":"Rocky River","railroad_dr":"Railroad Drive","conrail_rr":"Conrail Railroad","st_joseph_river":"Saint Joseph River","n_main_st":"North Main Street","s_main_st":"South Main Street","water_st":"Water Street","foster_st":"Foster Street","portage_river":"Portage River","flower_st":"Flower Street","elm_st":"Elm Street","walnut_st":"Walnut Street","morris_ave":"Morris Avenue","east_st":"East Street","portage_ave":"Portage Avenue"},"navigation":{"title":"Navigation","drag":"The main map area shows OpenStreetMap data on top of a background. You can navigate by dragging and scrolling, just like any web map. **Drag the map!**","select":"Map features are represented three ways: using points, lines or areas. All features can be selected by clicking on them. **Click on the point to select it.**","pane":"When a feature is selected, the feature editor is displayed. The header shows us the feature type and the main pane shows the feature's attributes, such as its name and address. **Close the feature editor by pressing the {button} button in the top right.**","search":"You can also search for features in the current view, or worldwide. **Search for '{name}'**","choose":"**Choose {name} from the list to select it.**","chosen":"Great! {name} is now selected. **Close the feature editor by pressing the {button} button.**"},"points":{"title":"Points","add":"Points can be used to represent features such as shops, restaurants, and monuments. They mark a specific location, and describe what's there. **Click the {button} Point button to add a new point.**","place":"The point can be placed by clicking on the map. **Click the map to place the new point on top of the building.**","search":"There are many different features that can be represented by points. The point you just added is a Cafe. **Search for '{name}'**","choose":"**Choose Cafe from the list.**","describe":"The point is now marked as a cafe. Using the feature editor, we can add more information about the feature. **Add a name**","close":"The feature editor will remember all of your changes automatically. When you change a feature, the close button will change to a checkmark. **Click the {button} button to close the feature editor**","reselect":"Often points will already exist, but have mistakes or be incomplete. We can edit existing points. **Click to select the point you just created.**","fixname":"**Change the name, then click the {button} button to close the feature editor.**","reselect_delete":"All features on the map can be deleted. **Click to select the point you created.**","delete":"The menu around the point contains operations that can be performed on it, including delete. **Click on the {button} button to delete the point.**"},"areas":{"title":"Areas","add":"Areas are used to show the boundaries of features like lakes, buildings, and residential areas. They can be also be used for more detailed mapping of many features you might normally map as points. **Click the {button} Area button to add a new area.**","corner":"Areas are drawn by placing nodes that mark the boundary of the area. **Click to place a starting node on one of the corners of the playground.**","place":"Draw the area by placing more nodes. Finish the area by clicking on the starting node. **Draw an area for the playground.**","search":"**Search for '{name}'.**","choose":"**Choose Playground from the list.**","describe":"**Add a name, then click the {button} button to close the feature editor**"},"lines":{"title":"Lines","add":"Lines are used to represent features such as roads, railroads, and rivers. **Click the {button} Line button to add a new line.**","start":"**Start the line by clicking on the end of the road.**","intersect":"Click to add more nodes to the line. You can drag the map while drawing if necessary. Roads, and many other types of lines, are part of a larger network. It is important for these lines to be connected properly in order for routing applications to work. **Click on {name} to create an intersection connecting the two lines.**","finish":"Lines can be finished by clicking on the last node again. **Finish drawing the road.**","road":"**Select Road from the list**","residential":"There are different types of roads, the most common of which is Residential. **Choose the Residential road type**","describe":"**Name the road, then click the {button} button to close the feature editor.**","restart":"The road needs to intersect {name}.","wrong_preset":"You didn't select the Residential road type. **Click here to choose again**"},"startediting":{"title":"Start Editing","help":"You can replay this walkthrough or view more documentation by clicking the {button} Help button.","save":"Don't forget to regularly save your changes!","start":"Start mapping!"}},"presets":{"categories":{"category-barrier":{"name":"Barrier Features"},"category-building":{"name":"Building Features"},"category-golf":{"name":"Golf Features"},"category-landuse":{"name":"Land Use Features"},"category-path":{"name":"Path Features"},"category-rail":{"name":"Rail Features"},"category-restriction":{"name":"Restriction Features"},"category-road":{"name":"Road Features"},"category-route":{"name":"Route Features"},"category-water-area":{"name":"Water Features"},"category-water-line":{"name":"Water Features"}},"fields":{"access_simple":{"label":"Allowed Access"},"access_toilets":{"label":"Access"},"access":{"label":"Allowed Access","placeholder":"Not Specified","types":{"access":"All","foot":"Foot","motor_vehicle":"Motor Vehicles","bicycle":"Bicycles","horse":"Horses"},"options":{"yes":{"title":"Allowed","description":"Access permitted by law; a right of way"},"no":{"title":"Prohibited","description":"Access not permitted to the general public"},"permissive":{"title":"Permissive","description":"Access permitted until such time as the owner revokes the permission"},"private":{"title":"Private","description":"Access permitted only with permission of the owner on an individual basis"},"designated":{"title":"Designated","description":"Access permitted according to signs or specific local laws"},"destination":{"title":"Destination","description":"Access permitted only to reach a destination"},"dismount":{"title":"Dismount","description":"Access permitted but rider must dismount"}}},"address":{"label":"Address","placeholders":{"city":"City","conscriptionnumber":"123","country":"Country","district":"District","floor":"Floor","hamlet":"Hamlet","housename":"Housename","housenumber":"123","place":"Place","postcode":"Postcode","province":"Province","state":"State","street":"Street","subdistrict":"Subdistrict","suburb":"Suburb"}},"admin_level":{"label":"Admin Level"},"aerialway":{"label":"Type"},"aerialway/access":{"label":"Access","options":{"entry":"Entry","exit":"Exit","both":"Both"}},"aerialway/bubble":{"label":"Bubble"},"aerialway/capacity":{"label":"Capacity (per hour)","placeholder":"500, 2500, 5000..."},"aerialway/duration":{"label":"Duration (minutes)","placeholder":"1, 2, 3..."},"aerialway/heating":{"label":"Heated"},"aerialway/occupancy":{"label":"Occupancy","placeholder":"2, 4, 8..."},"aerialway/summer/access":{"label":"Access (summer)","options":{"entry":"Entry","exit":"Exit","both":"Both"}},"aeroway":{"label":"Type"},"amenity":{"label":"Type"},"area/highway":{"label":"Type"},"artist":{"label":"Artist"},"artwork_type":{"label":"Type"},"atm":{"label":"ATM"},"backrest":{"label":"Backrest"},"barrier":{"label":"Type"},"beauty":{"label":"Shop Type"},"bench":{"label":"Bench"},"bicycle_parking":{"label":"Type"},"bin":{"label":"Waste Bin"},"blood_components":{"label":"Blood Components","options":{"whole":"whole blood","plasma":"plasma","platelets":"platelets","stemcells":"stem cell samples"}},"board_type":{"label":"Type"},"boundary":{"label":"Type"},"brand":{"label":"Brand"},"building_area":{"label":"Building"},"building":{"label":"Building"},"capacity":{"label":"Capacity","placeholder":"50, 100, 200..."},"cardinal_direction":{"label":"Direction","options":{"N":"North","E":"East","S":"South","W":"West","NE":"Northeast","SE":"Southeast","SW":"Southwest","NW":"Northwest","NNE":"North-northeast","ENE":"East-northeast","ESE":"East-southeast","SSE":"South-southeast","SSW":"South-southwest","WSW":"West-southwest","WNW":"West-northwest","NNW":"North-northwest"}},"clock_direction":{"label":"Direction","options":{"clockwise":"Clockwise","anticlockwise":"Counterclockwise"}},"collection_times":{"label":"Collection Times"},"construction":{"label":"Type"},"content":{"label":"Contents"},"country":{"label":"Country"},"covered":{"label":"Covered"},"craft":{"label":"Type"},"crop":{"label":"Crop"},"crossing":{"label":"Type"},"cuisine":{"label":"Cuisine"},"currency_multi":{"label":"Currency Types"},"cycle_network":{"label":"Network"},"cycleway":{"label":"Bike Lanes","placeholder":"none","types":{"cycleway:left":"Left side","cycleway:right":"Right side"},"options":{"none":{"title":"None","description":"No bike lane"},"lane":{"title":"Standard bike lane","description":"A bike lane separated from auto traffic by a painted line"},"shared_lane":{"title":"Shared bike lane","description":"A bike lane with no separation from auto traffic"},"track":{"title":"Bike track","description":"A bike lane separated from traffic by a physical barrier"},"share_busway":{"title":"Bike lane shared with bus","description":"A bike lane shared with a bus lane"},"opposite_lane":{"title":"Opposite bike lane","description":"A bike lane that travels in the opposite direction of traffic"},"opposite":{"title":"Contraflow bike lane","description":"A bike lane that travels in both directions on a one-way street"}}},"date":{"label":"Date"},"delivery":{"label":"Delivery"},"denomination":{"label":"Denomination"},"denotation":{"label":"Denotation"},"description":{"label":"Description"},"diaper":{"label":"Diaper Changing Available"},"display":{"label":"Display"},"dock":{"label":"Type"},"drive_through":{"label":"Drive-Through"},"electrified":{"label":"Electrification","placeholder":"Contact Line, Electrified Rail...","options":{"contact_line":"Contact Line","rail":"Electrified Rail","yes":"Yes (unspecified)","no":"No"}},"elevation":{"label":"Elevation"},"emergency":{"label":"Emergency"},"entrance":{"label":"Type"},"except":{"label":"Exceptions"},"fax":{"label":"Fax","placeholder":"+31 42 123 4567"},"fee":{"label":"Fee"},"fire_hydrant/type":{"label":"Type","options":{"pillar":"Pillar/Aboveground","underground":"Underground","wall":"Wall","pond":"Pond"}},"fixme":{"label":"Fix Me"},"fuel_multi":{"label":"Fuel Types"},"fuel":{"label":"Fuel"},"gauge":{"label":"Gauge"},"gender":{"label":"Gender","placeholder":"Unknown","options":{"male":"Male","female":"Female","unisex":"Unisex"}},"generator/method":{"label":"Method"},"generator/source":{"label":"Source"},"generator/type":{"label":"Type"},"golf_hole":{"label":"Reference","placeholder":"Hole number (1-18)"},"handicap":{"label":"Handicap","placeholder":"1-18"},"handrail":{"label":"Handrail"},"height":{"label":"Height (meters)"},"highway":{"label":"Type"},"historic":{"label":"Type"},"hoops":{"label":"Hoops","placeholder":"1, 2, 4..."},"iata":{"label":"IATA"},"icao":{"label":"ICAO"},"incline_steps":{"label":"Incline","options":{"up":"Up","down":"Down"}},"incline":{"label":"Incline"},"indoor":{"label":"Indoor"},"information":{"label":"Type"},"internet_access":{"label":"Internet Access","options":{"yes":"Yes","no":"No","wlan":"Wifi","wired":"Wired","terminal":"Terminal"}},"internet_access/fee":{"label":"Internet Access Fee"},"kerb":{"label":"Curb Ramp"},"lamp_type":{"label":"Type"},"landuse":{"label":"Type"},"lanes":{"label":"Lanes","placeholder":"1, 2, 3..."},"layer":{"label":"Layer"},"leaf_cycle_singular":{"label":"Leaf Cycle","options":{"evergreen":"Evergreen","deciduous":"Deciduous","semi_evergreen":"Semi-Evergreen","semi_deciduous":"Semi-Deciduous"}},"leaf_cycle":{"label":"Leaf Cycle","options":{"evergreen":"Evergreen","deciduous":"Deciduous","semi_evergreen":"Semi-Evergreen","semi_deciduous":"Semi-Deciduous","mixed":"Mixed"}},"leaf_type_singular":{"label":"Leaf Type","options":{"broadleaved":"Broadleaved","needleleaved":"Needleleaved","leafless":"Leafless"}},"leaf_type":{"label":"Leaf Type","options":{"broadleaved":"Broadleaved","needleleaved":"Needleleaved","mixed":"Mixed","leafless":"Leafless"}},"leisure":{"label":"Type"},"length":{"label":"Length (Meters)"},"level":{"label":"Level"},"levels":{"label":"Levels","placeholder":"2, 4, 6..."},"lit":{"label":"Lit"},"location":{"label":"Location"},"man_made":{"label":"Type"},"map_size":{"label":"Coverage"},"map_type":{"label":"Type"},"maxspeed":{"label":"Speed Limit","placeholder":"40, 50, 60..."},"maxstay":{"label":"Max Stay"},"mtb/scale":{"label":"Mountain Biking Difficulty","placeholder":"0, 1, 2, 3...","options":{"0":"0: Solid gravel/packed earth, no obstacles, wide curves","1":"1: Some loose surface, small obstacles, wide curves","2":"2: Much loose surface, large obstacles, easy hairpins","3":"3: Slippery surface, large obstacles, tight hairpins","4":"4: Loose surface or boulders, dangerous hairpins","5":"5: Maximum difficulty, boulder fields, landslides","6":"6: Not rideable except by the very best mountain bikers"}},"mtb/scale/imba":{"label":"IMBA Trail Difficulty","placeholder":"Easy, Medium, Difficult...","options":{"0":"Easiest (white circle)","1":"Easy (green circle)","2":"Medium (blue square)","3":"Difficult (black diamond)","4":"Extremely Difficult (double black diamond)"}},"mtb/scale/uphill":{"label":"Mountain Biking Uphill Difficulty","placeholder":"0, 1, 2, 3...","options":{"0":"0: Avg. incline <10%, gravel/packed earth, no obstacles","1":"1: Avg. incline <15%, gravel/packed earth, few small objects","2":"2: Avg. incline <20%, stable surface, fistsize rocks/roots","3":"3: Avg. incline <25%, variable surface, fistsize rocks/branches","4":"4: Avg. incline <30%, poor condition, big rocks/branches","5":"5: Very steep, bike generally needs to be pushed or carried"}},"name":{"label":"Name","placeholder":"Common name (if any)"},"natural":{"label":"Natural"},"network_bicycle":{"label":"Network Type","placeholder":"Local, Regional, National, International","options":{"lcn":"Local","rcn":"Regional","ncn":"National","icn":"International"}},"network_foot":{"label":"Network Type","placeholder":"Local, Regional, National, International","options":{"lwn":"Local","rwn":"Regional","nwn":"National","iwn":"International"}},"network_horse":{"label":"Network Type","placeholder":"Local, Regional, National, International","options":{"lhn":"Local","rhn":"Regional","nhn":"National","ihn":"International"}},"network_road":{"label":"Network"},"network":{"label":"Network"},"note":{"label":"Note"},"office":{"label":"Type"},"oneway_yes":{"label":"One Way","options":{"undefined":"Assumed to be Yes","yes":"Yes","no":"No"}},"oneway":{"label":"One Way","options":{"undefined":"Assumed to be No","yes":"Yes","no":"No"}},"opening_hours":{"label":"Hours"},"operator":{"label":"Operator"},"par":{"label":"Par","placeholder":"3, 4, 5..."},"parallel_direction":{"label":"Direction","options":{"forward":"Forward","backward":"Backward"}},"park_ride":{"label":"Park and Ride"},"parking":{"label":"Type","options":{"surface":"Surface","multi-storey":"Multilevel","underground":"Underground","sheds":"Sheds","carports":"Carports","garage_boxes":"Garage Boxes","lane":"Roadside Lane"}},"payment_multi":{"label":"Payment Types"},"phone":{"label":"Phone","placeholder":"+31 42 123 4567"},"piste/difficulty":{"label":"Difficulty","placeholder":"Easy, Intermediate, Advanced...","options":{"novice":"Novice (instructional)","easy":"Easy (green circle)","intermediate":"Intermediate (blue square)","advanced":"Advanced (black diamond)","expert":"Expert (double black diamond)","freeride":"Freeride (off-piste)","extreme":"Extreme (climbing equipment required)"}},"piste/grooming":{"label":"Grooming","options":{"classic":"Classic","mogul":"Mogul","backcountry":"Backcountry","classic+skating":"Classic and Skating","scooter":"Scooter/Snowmobile","skating":"Skating"}},"piste/type":{"label":"Type","options":{"downhill":"Downhill","nordic":"Nordic","skitour":"Skitour","sled":"Sled","hike":"Hike","sleigh":"Sleigh","ice_skate":"Ice Skate","snow_park":"Snow Park","playground":"Playground"}},"place":{"label":"Type"},"population":{"label":"Population"},"power_supply":{"label":"Power Supply"},"power":{"label":"Type"},"railway":{"label":"Type"},"recycling_accepts":{"label":"Accepts"},"recycling_type":{"label":"Recycling Type","options":{"container":"Container","centre":"Recycling Center"}},"ref":{"label":"Reference"},"relation":{"label":"Type"},"religion":{"label":"Religion"},"restriction":{"label":"Type"},"restrictions":{"label":"Turn Restrictions"},"rooms":{"label":"Rooms"},"route_master":{"label":"Type"},"route":{"label":"Type"},"sac_scale":{"label":"Hiking Difficulty","placeholder":"Mountain Hiking, Alpine Hiking...","options":{"hiking":"T1: Hiking","mountain_hiking":"T2: Mountain Hiking","demanding_mountain_hiking":"T3: Demanding Mountain Hiking","alpine_hiking":"T4: Alpine Hiking","demanding_alpine_hiking":"T5: Demanding Alpine Hiking","difficult_alpine_hiking":"T6: Difficult Alpine Hiking"}},"sanitary_dump_station":{"label":"Toilet Disposal"},"seasonal":{"label":"Seasonal"},"second_hand":{"label":"Sells Used","placeholder":"Yes, No, Only","options":{"yes":"Yes","no":"No","only":"Only"}},"service_rail":{"label":"Service Type","options":{"spur":"Spur","yard":"Yard","siding":"Siding","crossover":"Crossover"}},"service":{"label":"Type"},"service/bicycle":{"label":"Services"},"shelter_type":{"label":"Type"},"shelter":{"label":"Shelter"},"shop":{"label":"Type"},"site":{"label":"Type"},"smoking":{"label":"Smoking","placeholder":"No, Separated, Yes...","options":{"no":"No smoking anywhere","separated":"In smoking areas, not physically isolated","isolated":"In smoking areas, physically isolated","outside":"Allowed outside","yes":"Allowed everywhere","dedicated":"Dedicated to smokers (e.g. smokers' club)"}},"smoothness":{"label":"Smoothness","placeholder":"Thin Rollers, Wheels, Off-Road...","options":{"excellent":"Thin Rollers: rollerblade, skateboard","good":"Thin Wheels: racing bike","intermediate":"Wheels: city bike, wheelchair, scooter","bad":"Robust Wheels: trekking bike, car, rickshaw","very_bad":"High Clearance: light duty off-road vehicle","horrible":"Off-Road: heavy duty off-road vehicle","very_horrible":"Specialized off-road: tractor, ATV","impassable":"Impassable / No wheeled vehicle"}},"social_facility_for":{"label":"People served","placeholder":"Homeless, Disabled, Child, etc"},"source":{"label":"Source"},"sport_ice":{"label":"Sport"},"sport_racing":{"label":"Sport"},"sport":{"label":"Sport"},"stars":{"label":"Stars"},"stop":{"label":"Stop Type","options":{"all":"All Ways","minor":"Minor Road"}},"structure":{"label":"Structure","placeholder":"Unknown","options":{"bridge":"Bridge","tunnel":"Tunnel","embankment":"Embankment","cutting":"Cutting","ford":"Ford"}},"studio":{"label":"Type"},"substation":{"label":"Type"},"supervised":{"label":"Supervised"},"support":{"label":"Support"},"surface":{"label":"Surface"},"tactile_paving":{"label":"Tactile Paving"},"takeaway":{"label":"Takeaway","placeholder":"Yes, No, Takeaway Only...","options":{"yes":"Yes","no":"No","only":"Takeaway Only"}},"toilets/disposal":{"label":"Disposal","options":{"flush":"Flush","pitlatrine":"Pit/Latrine","chemical":"Chemical","bucket":"Bucket"}},"tourism":{"label":"Type"},"tower/construction":{"label":"Construction","placeholder":"Guyed, Lattice, Concealed, ..."},"tower/type":{"label":"Type"},"tracktype":{"label":"Track Type","placeholder":"Solid, Mostly Solid, Soft...","options":{"grade1":"Solid: paved or heavily compacted hardcore surface","grade2":"Mostly Solid: gravel/rock with some soft material mixed in","grade3":"Even mixture of hard and soft materials","grade4":"Mostly Soft: soil/sand/grass with some hard material mixed in","grade5":"Soft: soil/sand/grass"}},"traffic_calming":{"label":"Type"},"traffic_signals":{"label":"Type"},"trail_visibility":{"label":"Trail Visibility","placeholder":"Excellent, Good, Bad...","options":{"excellent":"Excellent: unambiguous path or markers everywhere","good":"Good: markers visible, sometimes require searching","intermediate":"Intermediate: few markers, path mostly visible","bad":"Bad: no markers, path sometimes invisible/pathless","horrible":"Horrible: often pathless, some orientation skills required","no":"No: pathless, excellent orientation skills required"}},"trees":{"label":"Trees"},"tunnel":{"label":"Tunnel"},"vending":{"label":"Type of Goods"},"visibility":{"label":"Visibility","options":{"house":"Up to 5m (16ft)","street":"5 to 20m (16 to 65ft)","area":"Over 20m (65ft)"}},"water_point":{"label":"Water Point"},"water":{"label":"Type"},"waterway":{"label":"Type"},"website":{"label":"Website","placeholder":"http://example.com/"},"wetland":{"label":"Type"},"wheelchair":{"label":"Wheelchair Access"},"width":{"label":"Width (Meters)"},"wikipedia":{"label":"Wikipedia"}},"presets":{"aerialway":{"name":"Aerialway","terms":"ski lift,funifor,funitel"},"aeroway":{"name":"Aeroway","terms":""},"amenity":{"name":"Amenity","terms":""},"highway":{"name":"Highway","terms":""},"place":{"name":"Place","terms":""},"power":{"name":"Power","terms":""},"railway":{"name":"Railway","terms":""},"roundabout":{"name":"Roundabout","terms":""},"waterway":{"name":"Waterway","terms":""},"address":{"name":"Address","terms":""},"advertising/billboard":{"name":"Billboard","terms":""},"aerialway/cable_car":{"name":"Cable Car","terms":"tramway,ropeway"},"aerialway/chair_lift":{"name":"Chair Lift","terms":""},"aerialway/gondola":{"name":"Gondola","terms":""},"aerialway/magic_carpet":{"name":"Magic Carpet Lift","terms":""},"aerialway/platter":{"name":"Platter Lift","terms":"button lift,poma lift"},"aerialway/pylon":{"name":"Aerialway Pylon","terms":""},"aerialway/rope_tow":{"name":"Rope Tow Lift","terms":"handle tow,bugel lift"},"aerialway/station":{"name":"Aerialway Station","terms":""},"aerialway/t-bar":{"name":"T-bar Lift","terms":""},"aeroway/aerodrome":{"name":"Airport","terms":"airplane,airport,aerodrome"},"aeroway/apron":{"name":"Apron","terms":"ramp"},"aeroway/gate":{"name":"Airport gate","terms":""},"aeroway/hangar":{"name":"Hangar","terms":""},"aeroway/helipad":{"name":"Helipad","terms":"helicopter,helipad,heliport"},"aeroway/runway":{"name":"Runway","terms":"landing strip"},"aeroway/taxiway":{"name":"Taxiway","terms":""},"aeroway/terminal":{"name":"Airport terminal","terms":"airport,aerodrome"},"amenity/register_office":{"name":"Register Office","terms":""},"amenity/swimming_pool":{"name":"Swimming Pool","terms":""},"amenity/arts_centre":{"name":"Arts Center","terms":""},"amenity/atm":{"name":"ATM","terms":"money,cash,machine"},"amenity/bank":{"name":"Bank","terms":"credit union,check,deposit,fund,investment,repository,reserve,safe,savings,stock,treasury,trust,vault"},"amenity/bar":{"name":"Bar","terms":"dive,beer,bier,booze"},"amenity/bbq":{"name":"Barbecue/Grill","terms":"bbq,grill"},"amenity/bench":{"name":"Bench","terms":"seat"},"amenity/bicycle_parking":{"name":"Bicycle Parking","terms":"bike"},"amenity/bicycle_rental":{"name":"Bicycle Rental","terms":"bike"},"amenity/bicycle_repair_station":{"name":"Bicycle Repair Tool Stand","terms":"bike,repair,chain,pump"},"amenity/biergarten":{"name":"Beer Garden","terms":"beer,bier,booze"},"amenity/boat_rental":{"name":"Boat Rental","terms":""},"amenity/bureau_de_change":{"name":"Currency Exchange","terms":"bureau de change,money changer"},"amenity/bus_station":{"name":"Bus Station","terms":""},"amenity/cafe":{"name":"Cafe","terms":"bistro,coffee,tea"},"amenity/car_rental":{"name":"Car Rental","terms":""},"amenity/car_sharing":{"name":"Car Sharing","terms":""},"amenity/car_wash":{"name":"Car Wash","terms":""},"amenity/casino":{"name":"Casino","terms":"gambling,roulette,craps,poker,blackjack"},"amenity/charging_station":{"name":"Charging Station","terms":"EV,Electric Vehicle,Supercharger"},"amenity/childcare":{"name":"Nursery/Childcare","terms":"daycare,orphanage,playgroup"},"amenity/cinema":{"name":"Cinema","terms":"drive-in,film,flick,movie,theater,picture,show,screen"},"amenity/clinic":{"name":"Clinic","terms":"medical,urgentcare"},"amenity/clock":{"name":"Clock","terms":""},"amenity/college":{"name":"College Grounds","terms":"university"},"amenity/community_centre":{"name":"Community Center","terms":"event,hall"},"amenity/compressed_air":{"name":"Compressed Air","terms":""},"amenity/courthouse":{"name":"Courthouse","terms":""},"amenity/coworking_space":{"name":"Coworking Space","terms":"coworking,office"},"amenity/dentist":{"name":"Dentist","terms":"tooth,teeth"},"amenity/doctors":{"name":"Doctor","terms":"medic*"},"amenity/dojo":{"name":"Dojo / Martial Arts Academy","terms":"martial arts,dojang"},"amenity/drinking_water":{"name":"Drinking Water","terms":"fountain,potable"},"amenity/embassy":{"name":"Embassy","terms":""},"amenity/fast_food":{"name":"Fast Food","terms":"restaurant,takeaway"},"amenity/ferry_terminal":{"name":"Ferry Terminal","terms":""},"amenity/fire_station":{"name":"Fire Station","terms":""},"amenity/fountain":{"name":"Fountain","terms":""},"amenity/fuel":{"name":"Gas Station","terms":"petrol,fuel,gasoline,propane,diesel,lng,cng,biodiesel"},"amenity/grave_yard":{"name":"Graveyard","terms":""},"amenity/grit_bin":{"name":"Grit Bin","terms":"salt,sand"},"amenity/hospital":{"name":"Hospital Grounds","terms":"clinic,doctor,emergency room,health service,hospice,infirmary,institution,nursing home,sanatorium,sanitarium,sick,surgery,ward"},"amenity/hunting_stand":{"name":"Hunting Stand","terms":""},"amenity/ice_cream":{"name":"Ice Cream Shop","terms":"gelato,sorbet,sherbet,frozen,yogurt"},"amenity/internet_cafe":{"name":"Internet Cafe","terms":"cybercafe,taxiphone,teleboutique,coffee,cafe,net,lanhouse"},"amenity/kindergarten":{"name":"Preschool/Kindergarten Grounds","terms":"kindergarden,pre-school"},"amenity/library":{"name":"Library","terms":"book"},"amenity/marketplace":{"name":"Marketplace","terms":""},"amenity/motorcycle_parking":{"name":"Motorcycle Parking","terms":""},"amenity/nightclub":{"name":"Nightclub","terms":"disco*,night club,dancing,dance club"},"amenity/parking_entrance":{"name":"Parking Garage Entrance/Exit","terms":""},"amenity/parking_space":{"name":"Parking Space","terms":""},"amenity/parking":{"name":"Car Parking","terms":""},"amenity/pharmacy":{"name":"Pharmacy","terms":"drug*,med*,prescription"},"amenity/place_of_worship":{"name":"Place of Worship","terms":"abbey,basilica,bethel,cathedral,chancel,chantry,chapel,church,fold,house of God,house of prayer,house of worship,minster,mission,mosque,oratory,parish,sacellum,sanctuary,shrine,synagogue,tabernacle,temple"},"amenity/place_of_worship/buddhist":{"name":"Buddhist Temple","terms":"stupa,vihara,monastery,temple,pagoda,zendo,dojo"},"amenity/place_of_worship/christian":{"name":"Church","terms":"christian,abbey,basilica,bethel,cathedral,chancel,chantry,chapel,fold,house of God,house of prayer,house of worship,minster,mission,oratory,parish,sacellum,sanctuary,shrine,tabernacle,temple"},"amenity/place_of_worship/jewish":{"name":"Synagogue","terms":"jewish"},"amenity/place_of_worship/muslim":{"name":"Mosque","terms":"muslim"},"amenity/planetarium":{"name":"Planetarium","terms":"museum,astronomy,observatory"},"amenity/police":{"name":"Police","terms":"badge,constable,constabulary,cop,detective,fed,law,enforcement,officer,patrol"},"amenity/post_box":{"name":"Mailbox","terms":"letter,post"},"amenity/post_office":{"name":"Post Office","terms":"letter,mail"},"amenity/prison":{"name":"Prison Grounds","terms":"cell,jail"},"amenity/pub":{"name":"Pub","terms":"dive,beer,bier,booze"},"amenity/public_bookcase":{"name":"Public Bookcase","terms":"library,bookcrossing"},"amenity/ranger_station":{"name":"Ranger Station","terms":"visitor center,visitor centre,permit center,permit centre,backcountry office,warden office,warden center"},"amenity/recycling_centre":{"name":"Recycling Center","terms":"bottle,can,dump,glass,garbage,rubbish,scrap,trash"},"amenity/recycling":{"name":"Recycling","terms":"bin,can,bottle,glass,garbage,rubbish,scrap,trash"},"amenity/restaurant":{"name":"Restaurant","terms":"bar,breakfast,cafe,café,canteen,coffee,dine,dining,dinner,drive-in,eat,grill,lunch,table"},"amenity/sanitary_dump_station":{"name":"RV Toilet Disposal","terms":"Motor Home,Camper,Sanitary,Dump Station,Elsan,CDP,CTDP,Chemical Toilet"},"amenity/school":{"name":"School Grounds","terms":"academy,elementary school,middle school,high school"},"amenity/shelter":{"name":"Shelter","terms":"lean-to,gazebo,picnic"},"amenity/social_facility":{"name":"Social Facility","terms":""},"amenity/social_facility/food_bank":{"name":"Food Bank","terms":""},"amenity/social_facility/group_home":{"name":"Elderly Group Home","terms":"old,senior,living"},"amenity/social_facility/homeless_shelter":{"name":"Homeless Shelter","terms":"houseless,unhoused,displaced"},"amenity/studio":{"name":"Studio","terms":"recording,radio,television"},"amenity/taxi":{"name":"Taxi Stand","terms":"cab"},"amenity/telephone":{"name":"Telephone","terms":"phone"},"amenity/theatre":{"name":"Theater","terms":"theatre,performance,play,musical"},"amenity/toilets":{"name":"Toilets","terms":"bathroom,restroom,outhouse,privy,head,lavatory,latrine,water closet,WC,W.C."},"amenity/townhall":{"name":"Town Hall","terms":"village,city,government,courthouse,municipal"},"amenity/university":{"name":"University Grounds","terms":"college"},"amenity/vending_machine/cigarettes":{"name":"Cigarette Vending Machine","terms":"cigarette"},"amenity/vending_machine/condoms":{"name":"Condom Vending Machine","terms":"condom"},"amenity/vending_machine/drinks":{"name":"Drink Vending Machine","terms":"drink,soda,beverage,juice,pop"},"amenity/vending_machine/excrement_bags":{"name":"Excrement Bag Vending Machine","terms":"excrement bags,poop,dog,animal"},"amenity/vending_machine/news_papers":{"name":"Newspaper Vending Machine","terms":"newspaper"},"amenity/vending_machine/parcel_pickup_dropoff":{"name":"Parcel Pickup/Dropoff Vending Machine","terms":"parcel,mail,pickup"},"amenity/vending_machine/parking_tickets":{"name":"Parking Ticket Vending Machine","terms":"parking,ticket"},"amenity/vending_machine/public_transport_tickets":{"name":"Transit Ticket Vending Machine","terms":"bus,train,ferry,rail,ticket,transportation"},"amenity/vending_machine/sweets":{"name":"Snack Vending Machine","terms":"candy,gum,chip,pretzel,cookie,cracker"},"amenity/vending_machine/vending_machine":{"name":"Vending Machine","terms":""},"amenity/veterinary":{"name":"Veterinary","terms":"pet clinic,veterinarian,animal hospital,pet doctor"},"amenity/waste_basket":{"name":"Waste Basket","terms":"bin,garbage,rubbish,litter,trash"},"amenity/waste_disposal":{"name":"Garbage Dumpster","terms":"garbage,rubbish,litter,trash"},"amenity/waste_transfer_station":{"name":"Waste Transfer Station","terms":"dump,garbage,recycling,rubbish,scrap,trash"},"amenity/water_point":{"name":"RV Drinking Water","terms":""},"area":{"name":"Area","terms":""},"area/highway":{"name":"Road Surface","terms":""},"barrier":{"name":"Barrier","terms":""},"barrier/entrance":{"name":"Entrance","terms":""},"barrier/block":{"name":"Block","terms":""},"barrier/bollard":{"name":"Bollard","terms":""},"barrier/cattle_grid":{"name":"Cattle Grid","terms":""},"barrier/city_wall":{"name":"City Wall","terms":""},"barrier/cycle_barrier":{"name":"Cycle Barrier","terms":""},"barrier/ditch":{"name":"Trench","terms":""},"barrier/fence":{"name":"Fence","terms":""},"barrier/gate":{"name":"Gate","terms":""},"barrier/hedge":{"name":"Hedge","terms":""},"barrier/kissing_gate":{"name":"Kissing Gate","terms":""},"barrier/lift_gate":{"name":"Lift Gate","terms":""},"barrier/retaining_wall":{"name":"Retaining Wall","terms":""},"barrier/stile":{"name":"Stile","terms":""},"barrier/toll_booth":{"name":"Toll Booth","terms":""},"barrier/wall":{"name":"Wall","terms":""},"boundary/administrative":{"name":"Administrative Boundary","terms":""},"building":{"name":"Building","terms":""},"building/bunker":{"name":"Bunker","terms":""},"building/entrance":{"name":"Entrance/Exit","terms":""},"building/train_station":{"name":"Train Station","terms":""},"building/apartments":{"name":"Apartments","terms":""},"building/barn":{"name":"Barn","terms":""},"building/cabin":{"name":"Cabin","terms":""},"building/cathedral":{"name":"Cathedral Building","terms":""},"building/chapel":{"name":"Chapel Building","terms":""},"building/church":{"name":"Church Building","terms":""},"building/college":{"name":"College Building","terms":"university"},"building/commercial":{"name":"Commercial Building","terms":""},"building/construction":{"name":"Building Under Construction","terms":""},"building/detached":{"name":"Detached House","terms":"home,single,family,residence,dwelling"},"building/dormitory":{"name":"Dormitory","terms":""},"building/garage":{"name":"Garage","terms":""},"building/garages":{"name":"Garages","terms":""},"building/greenhouse":{"name":"Greenhouse","terms":""},"building/hospital":{"name":"Hospital Building","terms":""},"building/hotel":{"name":"Hotel Building","terms":""},"building/house":{"name":"House","terms":"home,family,residence,dwelling"},"building/hut":{"name":"Hut","terms":""},"building/industrial":{"name":"Industrial Building","terms":""},"building/kindergarten":{"name":"Preschool/Kindergarten Building","terms":"kindergarden,pre-school"},"building/public":{"name":"Public Building","terms":""},"building/residential":{"name":"Residential Building","terms":""},"building/retail":{"name":"Retail Building","terms":""},"building/roof":{"name":"Roof","terms":""},"building/school":{"name":"School Building","terms":"academy,elementary school,middle school,high school"},"building/semidetached_house":{"name":"Semi-Detached House","terms":"home,double,duplex,twin,family,residence,dwelling"},"building/shed":{"name":"Shed","terms":""},"building/stable":{"name":"Stable","terms":""},"building/static_caravan":{"name":"Static Mobile Home","terms":""},"building/terrace":{"name":"Row Houses","terms":"home,terrace,brownstone,family,residence,dwelling"},"building/university":{"name":"University Building","terms":"college"},"building/warehouse":{"name":"Warehouse","terms":""},"camp_site/camp_pitch":{"name":"Camp Pitch","terms":"tent,rv"},"craft":{"name":"Craft","terms":""},"craft/jeweler":{"name":"Jeweler","terms":""},"craft/locksmith":{"name":"Locksmith","terms":""},"craft/optician":{"name":"Optician","terms":""},"craft/tailor":{"name":"Tailor","terms":"clothes,suit"},"craft/basket_maker":{"name":"Basket Maker","terms":""},"craft/beekeeper":{"name":"Beekeeper","terms":""},"craft/blacksmith":{"name":"Blacksmith","terms":""},"craft/boatbuilder":{"name":"Boat Builder","terms":""},"craft/bookbinder":{"name":"Bookbinder","terms":"book repair"},"craft/brewery":{"name":"Brewery","terms":"beer,bier"},"craft/carpenter":{"name":"Carpenter","terms":"woodworker"},"craft/carpet_layer":{"name":"Carpet Layer","terms":""},"craft/caterer":{"name":"Caterer","terms":""},"craft/clockmaker":{"name":"Clockmaker","terms":""},"craft/confectionery":{"name":"Confectionery","terms":"sweets,candy"},"craft/dressmaker":{"name":"Dressmaker","terms":"seamstress"},"craft/electrician":{"name":"Electrician","terms":"power,wire"},"craft/gardener":{"name":"Gardener","terms":"landscaper,grounds keeper"},"craft/glaziery":{"name":"Glaziery","terms":"glass,stained-glass,window"},"craft/handicraft":{"name":"Handicraft","terms":""},"craft/hvac":{"name":"HVAC","terms":"heat*,vent*,air conditioning"},"craft/insulator":{"name":"Insulator","terms":""},"craft/key_cutter":{"name":"Key Cutter","terms":""},"craft/metal_construction":{"name":"Metal Construction","terms":""},"craft/painter":{"name":"Painter","terms":""},"craft/photographer":{"name":"Photographer","terms":""},"craft/photographic_laboratory":{"name":"Photographic Laboratory","terms":"film"},"craft/plasterer":{"name":"Plasterer","terms":""},"craft/plumber":{"name":"Plumber","terms":"pipe"},"craft/pottery":{"name":"Pottery","terms":"ceramic"},"craft/rigger":{"name":"Rigger","terms":""},"craft/roofer":{"name":"Roofer","terms":""},"craft/saddler":{"name":"Saddler","terms":""},"craft/sailmaker":{"name":"Sailmaker","terms":""},"craft/sawmill":{"name":"Sawmill","terms":"lumber"},"craft/scaffolder":{"name":"Scaffolder","terms":""},"craft/sculpter":{"name":"Sculpter","terms":""},"craft/shoemaker":{"name":"Shoemaker","terms":"cobbler"},"craft/stonemason":{"name":"Stonemason","terms":"masonry"},"craft/sweep":{"name":"Chimney Sweep","terms":""},"craft/tiler":{"name":"Tiler","terms":""},"craft/tinsmith":{"name":"Tinsmith","terms":""},"craft/upholsterer":{"name":"Upholsterer","terms":""},"craft/watchmaker":{"name":"Watchmaker","terms":""},"craft/window_construction":{"name":"Window Construction","terms":"glass"},"craft/winery":{"name":"Winery","terms":""},"embankment":{"name":"Embankment","terms":""},"emergency/designated":{"name":"Emergency Access Designated","terms":""},"emergency/destination":{"name":"Emergency Access Destination","terms":""},"emergency/no":{"name":"Emergency Access No","terms":""},"emergency/official":{"name":"Emergency Access Official","terms":""},"emergency/private":{"name":"Emergency Access Private","terms":""},"emergency/yes":{"name":"Emergency Access Yes","terms":""},"emergency/ambulance_station":{"name":"Ambulance Station","terms":"EMS,EMT,rescue"},"emergency/defibrillator":{"name":"Defibrillator","terms":"AED"},"emergency/fire_hydrant":{"name":"Fire Hydrant","terms":""},"emergency/phone":{"name":"Emergency Phone","terms":""},"entrance":{"name":"Entrance/Exit","terms":""},"footway/crossing":{"name":"Street Crossing","terms":""},"footway/crosswalk":{"name":"Pedestrian Crosswalk","terms":"zebra crossing"},"footway/sidewalk":{"name":"Sidewalk","terms":""},"ford":{"name":"Ford","terms":""},"golf/bunker":{"name":"Sand Trap","terms":"hazard,bunker"},"golf/fairway":{"name":"Fairway","terms":""},"golf/green":{"name":"Putting Green","terms":""},"golf/hole":{"name":"Golf Hole","terms":""},"golf/lateral_water_hazard_area":{"name":"Lateral Water Hazard","terms":""},"golf/lateral_water_hazard_line":{"name":"Lateral Water Hazard","terms":""},"golf/rough":{"name":"Rough","terms":""},"golf/tee":{"name":"Tee Box","terms":"teeing ground"},"golf/water_hazard_area":{"name":"Water Hazard","terms":""},"golf/water_hazard_line":{"name":"Water Hazard","terms":""},"healthcare/blood_donation":{"name":"Blood Donor Center","terms":"blood bank,blood donation,blood transfusion,apheresis,plasmapheresis,plateletpheresis,stem cell donation"},"highway/bridleway":{"name":"Bridle Path","terms":"bridleway,equestrian,horse"},"highway/bus_stop":{"name":"Bus Stop","terms":""},"highway/corridor":{"name":"Indoor Corridor","terms":"gallery,hall,hallway,indoor,passage,passageway"},"highway/crossing":{"name":"Street Crossing","terms":""},"highway/crosswalk":{"name":"Pedestrian Crosswalk","terms":"zebra crossing"},"highway/cycleway":{"name":"Cycle Path","terms":"bike"},"highway/footway":{"name":"Foot Path","terms":"hike,hiking,trackway,trail,walk"},"highway/give_way":{"name":"Yield Sign","terms":"give way,yield,sign"},"highway/living_street":{"name":"Living Street","terms":""},"highway/mini_roundabout":{"name":"Mini-Roundabout","terms":""},"highway/motorway_junction":{"name":"Motorway Junction / Exit","terms":""},"highway/motorway_link":{"name":"Motorway Link","terms":"ramp,on ramp,off ramp"},"highway/motorway":{"name":"Motorway","terms":""},"highway/path":{"name":"Path","terms":"hike,hiking,trackway,trail,walk"},"highway/pedestrian":{"name":"Pedestrian Street","terms":""},"highway/primary_link":{"name":"Primary Link","terms":"ramp,on ramp,off ramp"},"highway/primary":{"name":"Primary Road","terms":""},"highway/raceway":{"name":"Motor Raceway","terms":"auto*,race*,nascar"},"highway/residential":{"name":"Residential Road","terms":""},"highway/rest_area":{"name":"Rest Area","terms":"rest stop"},"highway/road":{"name":"Unknown Road","terms":""},"highway/secondary_link":{"name":"Secondary Link","terms":"ramp,on ramp,off ramp"},"highway/secondary":{"name":"Secondary Road","terms":""},"highway/service":{"name":"Service Road","terms":""},"highway/service/alley":{"name":"Alley","terms":""},"highway/service/drive-through":{"name":"Drive-Through","terms":""},"highway/service/driveway":{"name":"Driveway","terms":""},"highway/service/emergency_access":{"name":"Emergency Access","terms":""},"highway/service/parking_aisle":{"name":"Parking Aisle","terms":""},"highway/services":{"name":"Service Area","terms":"services,travel plaza,service station"},"highway/steps":{"name":"Steps","terms":"stairs,staircase"},"highway/stop":{"name":"Stop Sign","terms":"stop,halt,sign"},"highway/street_lamp":{"name":"Street Lamp","terms":"streetlight,street light,lamp,light,gaslight"},"highway/tertiary_link":{"name":"Tertiary Link","terms":"ramp,on ramp,off ramp"},"highway/tertiary":{"name":"Tertiary Road","terms":""},"highway/track":{"name":"Unmaintained Track Road","terms":"woods road,forest road,logging road,fire road,farm road,agricultural road,ranch road,carriage road,primitive,unmaintained,rut,offroad,4wd,4x4,four wheel drive,atv,quad,jeep,double track,two track"},"highway/traffic_signals":{"name":"Traffic Signals","terms":"light,stoplight,traffic light"},"highway/trunk_link":{"name":"Trunk Link","terms":"ramp,on ramp,off ramp"},"highway/trunk":{"name":"Trunk Road","terms":""},"highway/turning_circle":{"name":"Turning Circle","terms":"cul-de-sac"},"highway/turning_loop":{"name":"Turning Loop (Island)","terms":"cul-de-sac"},"highway/unclassified":{"name":"Minor/Unclassified Road","terms":""},"historic":{"name":"Historic Site","terms":""},"historic/archaeological_site":{"name":"Archaeological Site","terms":""},"historic/boundary_stone":{"name":"Boundary Stone","terms":""},"historic/castle":{"name":"Castle","terms":""},"historic/memorial":{"name":"Memorial","terms":""},"historic/monument":{"name":"Monument","terms":""},"historic/ruins":{"name":"Ruins","terms":""},"historic/wayside_cross":{"name":"Wayside Cross","terms":""},"historic/wayside_shrine":{"name":"Wayside Shrine","terms":""},"junction":{"name":"Junction","terms":""},"landuse":{"name":"Land Use","terms":""},"landuse/farm":{"name":"Farmland","terms":""},"landuse/allotments":{"name":"Community Garden","terms":"allotment,garden"},"landuse/basin":{"name":"Basin","terms":""},"landuse/cemetery":{"name":"Cemetery","terms":""},"landuse/churchyard":{"name":"Churchyard","terms":""},"landuse/commercial":{"name":"Commercial Area","terms":""},"landuse/construction":{"name":"Construction","terms":""},"landuse/farmland":{"name":"Farmland","terms":""},"landuse/farmyard":{"name":"Farmyard","terms":""},"landuse/forest":{"name":"Forest","terms":"tree"},"landuse/garages":{"name":"Garages","terms":""},"landuse/grass":{"name":"Grass","terms":""},"landuse/industrial":{"name":"Industrial Area","terms":""},"landuse/landfill":{"name":"Landfill","terms":"dump"},"landuse/meadow":{"name":"Meadow","terms":""},"landuse/military":{"name":"Military Area","terms":""},"landuse/orchard":{"name":"Orchard","terms":""},"landuse/plant_nursery":{"name":"Plant Nursery","terms":"vivero"},"landuse/quarry":{"name":"Quarry","terms":""},"landuse/recreation_ground":{"name":"Recreation Ground","terms":"playing fields"},"landuse/residential":{"name":"Residential Area","terms":""},"landuse/retail":{"name":"Retail Area","terms":""},"landuse/vineyard":{"name":"Vineyard","terms":""},"leisure":{"name":"Leisure","terms":""},"leisure/adult_gaming_centre":{"name":"Adult Gaming Center","terms":"gambling,slot machine"},"leisure/bird_hide":{"name":"Bird Hide","terms":"machan,ornithology"},"leisure/bowling_alley":{"name":"Bowling Alley","terms":""},"leisure/common":{"name":"Common","terms":"open space"},"leisure/dog_park":{"name":"Dog Park","terms":""},"leisure/firepit":{"name":"Firepit","terms":"fireplace,campfire"},"leisure/fitness_centre":{"name":"Gym / Fitness Center","terms":"health,gym,leisure,studio"},"leisure/fitness_centre/yoga":{"name":"Yoga Studio","terms":"studio"},"leisure/fitness_station":{"name":"Outdoor Fitness Station","terms":"fitness,gym"},"leisure/garden":{"name":"Garden","terms":""},"leisure/golf_course":{"name":"Golf Course","terms":"links"},"leisure/ice_rink":{"name":"Ice Rink","terms":"hockey,skating,curling"},"leisure/marina":{"name":"Marina","terms":"boat"},"leisure/miniature_golf":{"name":"Miniature Golf","terms":"crazy golf,mini golf,putt-putt"},"leisure/nature_reserve":{"name":"Nature Reserve","terms":"protected,wildlife"},"leisure/park":{"name":"Park","terms":"esplanade,estate,forest,garden,grass,green,grounds,lawn,lot,meadow,parkland,place,playground,plaza,pleasure garden,recreation area,square,tract,village green,woodland"},"leisure/picnic_table":{"name":"Picnic Table","terms":"bench"},"leisure/pitch":{"name":"Sport Pitch","terms":"field"},"leisure/pitch/american_football":{"name":"American Football Field","terms":""},"leisure/pitch/baseball":{"name":"Baseball Diamond","terms":""},"leisure/pitch/basketball":{"name":"Basketball Court","terms":""},"leisure/pitch/bowls":{"name":"Bowling Green","terms":""},"leisure/pitch/rugby_league":{"name":"Rugby League Field","terms":""},"leisure/pitch/rugby_union":{"name":"Rugby Union Field","terms":""},"leisure/pitch/skateboard":{"name":"Skate Park","terms":""},"leisure/pitch/soccer":{"name":"Soccer Field","terms":""},"leisure/pitch/tennis":{"name":"Tennis Court","terms":""},"leisure/pitch/volleyball":{"name":"Volleyball Court","terms":""},"leisure/playground":{"name":"Playground","terms":"jungle gym,play area"},"leisure/running_track":{"name":"Running Track","terms":""},"leisure/slipway":{"name":"Slipway","terms":"boat launch,boat ramp"},"leisure/sports_centre":{"name":"Sports Center / Complex","terms":""},"leisure/sports_centre/swimming":{"name":"Swimming Pool Facility","terms":"dive,water"},"leisure/stadium":{"name":"Stadium","terms":""},"leisure/swimming_pool":{"name":"Swimming Pool","terms":"dive,water"},"leisure/track":{"name":"Racetrack (non-Motorsport)","terms":""},"leisure/water_park":{"name":"Water Park","terms":"swim,pool,dive"},"line":{"name":"Line","terms":""},"man_made":{"name":"Man Made","terms":""},"man_made/embankment":{"name":"Embankment","terms":""},"man_made/adit":{"name":"Adit","terms":"entrance,underground,mine,cave"},"man_made/breakwater":{"name":"Breakwater","terms":""},"man_made/bridge":{"name":"Bridge","terms":""},"man_made/chimney":{"name":"Chimney","terms":""},"man_made/cutline":{"name":"Cut line","terms":""},"man_made/flagpole":{"name":"Flagpole","terms":""},"man_made/gasometer":{"name":"Gasometer","terms":"gas holder"},"man_made/groyne":{"name":"Groyne","terms":""},"man_made/lighthouse":{"name":"Lighthouse","terms":""},"man_made/mast":{"name":"Radio Mast","terms":"broadcast tower,cell phone tower,cell tower,guyed tower,mobile phone tower,radio tower,television tower,transmission mast,transmission tower,tv tower"},"man_made/observation":{"name":"Observation Tower","terms":"lookout tower,fire tower"},"man_made/petroleum_well":{"name":"Oil Well","terms":"drilling rig,oil derrick,oil drill,oil horse,oil rig,oil pump,petroleum well,pumpjack"},"man_made/pier":{"name":"Pier","terms":"dock"},"man_made/pipeline":{"name":"Pipeline","terms":""},"man_made/pumping_station":{"name":"Pumping Station","terms":""},"man_made/silo":{"name":"Silo","terms":"grain,corn,wheat"},"man_made/storage_tank":{"name":"Storage Tank","terms":"water,oil,gas,petrol"},"man_made/surveillance":{"name":"Surveillance","terms":"cctv"},"man_made/survey_point":{"name":"Survey Point","terms":""},"man_made/tower":{"name":"Tower","terms":""},"man_made/wastewater_plant":{"name":"Wastewater Plant","terms":"sewage*,water treatment plant,reclamation plant"},"man_made/water_tower":{"name":"Water Tower","terms":""},"man_made/water_well":{"name":"Water Well","terms":""},"man_made/water_works":{"name":"Water Works","terms":""},"man_made/works":{"name":"Works","terms":"car assembly plant,aluminium processing plant,brewery,furniture manufacture factory,oil refinery,plastic recycling"},"military/airfield":{"name":"Airfield","terms":""},"military/barracks":{"name":"Barracks","terms":""},"military/bunker":{"name":"Bunker","terms":""},"military/checkpoint":{"name":"Checkpoint","terms":""},"military/danger_area":{"name":"Danger Area","terms":""},"military/naval_base":{"name":"Naval Base","terms":""},"military/obstacle_course":{"name":"Obstacle Course","terms":""},"military/range":{"name":"Military Range","terms":""},"military/training_area":{"name":"Training area","terms":""},"natural":{"name":"Natural","terms":""},"natural/bay":{"name":"Bay","terms":""},"natural/beach":{"name":"Beach","terms":""},"natural/cave_entrance":{"name":"Cave Entrance","terms":"cavern,hollow,grotto,shelter,cavity"},"natural/cliff":{"name":"Cliff","terms":""},"natural/coastline":{"name":"Coastline","terms":"shore"},"natural/fell":{"name":"Fell","terms":""},"natural/glacier":{"name":"Glacier","terms":""},"natural/grassland":{"name":"Grassland","terms":""},"natural/heath":{"name":"Heath","terms":""},"natural/peak":{"name":"Peak","terms":"acme,aiguille,alp,climax,crest,crown,hill,mount,mountain,pinnacle,summit,tip,top"},"natural/saddle":{"name":"Saddle","terms":"pass,mountain pass,top"},"natural/scree":{"name":"Scree","terms":"loose rocks"},"natural/scrub":{"name":"Scrub","terms":"bush,shrubs"},"natural/spring":{"name":"Spring","terms":""},"natural/tree_row":{"name":"Tree row","terms":""},"natural/tree":{"name":"Tree","terms":""},"natural/volcano":{"name":"Volcano","terms":"mountain,crater"},"natural/water":{"name":"Water","terms":""},"natural/water/lake":{"name":"Lake","terms":"lakelet,loch,mere"},"natural/water/pond":{"name":"Pond","terms":"lakelet,millpond,tarn,pool,mere"},"natural/water/reservoir":{"name":"Reservoir","terms":""},"natural/wetland":{"name":"Wetland","terms":""},"natural/wood":{"name":"Wood","terms":"tree"},"office":{"name":"Office","terms":""},"office/travel_agent":{"name":"Travel Agency","terms":""},"office/accountant":{"name":"Accountant","terms":""},"office/administrative":{"name":"Administrative Office","terms":""},"office/architect":{"name":"Architect","terms":""},"office/company":{"name":"Company Office","terms":""},"office/educational_institution":{"name":"Educational Institution","terms":""},"office/employment_agency":{"name":"Employment Agency","terms":"job"},"office/estate_agent":{"name":"Real Estate Office","terms":""},"office/financial":{"name":"Financial Office","terms":""},"office/government":{"name":"Government Office","terms":""},"office/government/register_office":{"name":"Register Office","terms":"clerk,marriage,death,birth,certificate"},"office/insurance":{"name":"Insurance Office","terms":""},"office/it":{"name":"IT Office","terms":""},"office/lawyer":{"name":"Law Office","terms":""},"office/newspaper":{"name":"Newspaper","terms":""},"office/ngo":{"name":"NGO Office","terms":""},"office/physician":{"name":"Physician","terms":""},"office/political_party":{"name":"Political Party","terms":""},"office/research":{"name":"Research Office","terms":""},"office/telecommunication":{"name":"Telecom Office","terms":""},"office/therapist":{"name":"Therapist","terms":""},"piste":{"name":"Piste/Ski Trail","terms":"ski,sled,sleigh,snowboard,nordic,downhill,snowmobile"},"place/city":{"name":"City","terms":""},"place/farm":{"name":"Farm","terms":""},"place/hamlet":{"name":"Hamlet","terms":""},"place/island":{"name":"Island","terms":"archipelago,atoll,bar,cay,isle,islet,key,reef"},"place/isolated_dwelling":{"name":"Isolated Dwelling","terms":""},"place/locality":{"name":"Locality","terms":""},"place/neighbourhood":{"name":"Neighborhood","terms":"neighbourhood"},"place/suburb":{"name":"Borough","terms":"Boro,Quarter"},"place/town":{"name":"Town","terms":""},"place/village":{"name":"Village","terms":""},"point":{"name":"Point","terms":""},"power/sub_station":{"name":"Substation","terms":""},"power/generator":{"name":"Power Generator","terms":""},"power/line":{"name":"Power Line","terms":""},"power/minor_line":{"name":"Minor Power Line","terms":""},"power/pole":{"name":"Power Pole","terms":""},"power/substation":{"name":"Substation","terms":""},"power/tower":{"name":"High-Voltage Tower","terms":""},"power/transformer":{"name":"Transformer","terms":""},"public_transport/platform":{"name":"Platform","terms":""},"public_transport/stop_position":{"name":"Stop Position","terms":""},"railway/abandoned":{"name":"Abandoned Railway","terms":""},"railway/crossing":{"name":"Railway Crossing (Path)","terms":"crossing,pedestrian crossing,railroad crossing,level crossing,grade crossing,path through railroad,train crossing"},"railway/disused":{"name":"Disused Railway","terms":""},"railway/funicular":{"name":"Funicular","terms":"venicular,cliff railway,cable car,cable railway,funicular railway"},"railway/halt":{"name":"Railway Halt","terms":"break,interrupt,rest,wait,interruption"},"railway/level_crossing":{"name":"Railway Crossing (Road)","terms":"crossing,railroad crossing,level crossing,grade crossing,road through railroad,train crossing"},"railway/monorail":{"name":"Monorail","terms":""},"railway/narrow_gauge":{"name":"Narrow Gauge Rail","terms":"narrow gauge railway,narrow gauge railroad"},"railway/platform":{"name":"Railway Platform","terms":""},"railway/rail":{"name":"Rail","terms":""},"railway/station":{"name":"Railway Station","terms":"train station,station"},"railway/subway_entrance":{"name":"Subway Entrance","terms":""},"railway/subway":{"name":"Subway","terms":""},"railway/tram":{"name":"Tram","terms":"streetcar"},"relation":{"name":"Relation","terms":""},"route/ferry":{"name":"Ferry Route","terms":""},"shop":{"name":"Shop","terms":""},"shop/fishmonger":{"name":"Fishmonger","terms":""},"shop/vacant":{"name":"Vacant Shop","terms":""},"shop/alcohol":{"name":"Liquor Store","terms":"alcohol,beer,booze,wine"},"shop/anime":{"name":"Anime Shop","terms":"manga,japan,cosplay,figurine,dakimakura"},"shop/antiques":{"name":"Antiques Shop","terms":""},"shop/art":{"name":"Art Store","terms":"art*,exhibit*,gallery"},"shop/baby_goods":{"name":"Baby Goods Store","terms":""},"shop/bag":{"name":"Bag/Luggage Store","terms":"handbag,purse"},"shop/bakery":{"name":"Bakery","terms":""},"shop/bathroom_furnishing":{"name":"Bathroom Furnishing Store","terms":""},"shop/beauty":{"name":"Beauty Shop","terms":"spa,salon,tanning"},"shop/beauty/nails":{"name":"Nail Salon","terms":"manicure,pedicure"},"shop/beauty/tanning":{"name":"Tanning Salon","terms":""},"shop/bed":{"name":"Bedding/Mattress Store","terms":""},"shop/beverages":{"name":"Beverage Store","terms":""},"shop/bicycle":{"name":"Bicycle Shop","terms":"bike,repair"},"shop/bookmaker":{"name":"Bookmaker","terms":"betting"},"shop/books":{"name":"Book Store","terms":""},"shop/boutique":{"name":"Boutique","terms":""},"shop/butcher":{"name":"Butcher","terms":"meat"},"shop/candles":{"name":"Candle Shop","terms":""},"shop/car_parts":{"name":"Car Parts Store","terms":"auto"},"shop/car_repair":{"name":"Car Repair Shop","terms":"auto,garage,service"},"shop/car":{"name":"Car Dealership","terms":"auto"},"shop/carpet":{"name":"Carpet Store","terms":"rug"},"shop/charity":{"name":"Charity Store","terms":"thrift,op shop,nonprofit"},"shop/cheese":{"name":"Cheese Store","terms":""},"shop/chemist":{"name":"Drugstore","terms":"med*,drug*,gift"},"shop/chocolate":{"name":"Chocolate Store","terms":""},"shop/clothes":{"name":"Clothing Store","terms":""},"shop/coffee":{"name":"Coffee Store","terms":""},"shop/computer":{"name":"Computer Store","terms":""},"shop/confectionery":{"name":"Candy Store","terms":""},"shop/convenience":{"name":"Convenience Store","terms":""},"shop/copyshop":{"name":"Copy Store","terms":""},"shop/cosmetics":{"name":"Cosmetics Store","terms":""},"shop/craft":{"name":"Arts and Crafts Store","terms":"art*,paint*,frame"},"shop/curtain":{"name":"Curtain Store","terms":"drape*,window"},"shop/dairy":{"name":"Dairy Store","terms":"milk,egg,cheese"},"shop/deli":{"name":"Deli","terms":"lunch,meat,sandwich"},"shop/department_store":{"name":"Department Store","terms":""},"shop/doityourself":{"name":"DIY Store","terms":""},"shop/dry_cleaning":{"name":"Dry Cleaner","terms":""},"shop/e-cigarette":{"name":"E-Cigarette Shop","terms":"electronic,vapor"},"shop/electronics":{"name":"Electronics Store","terms":"appliance,audio,computer,tv"},"shop/erotic":{"name":"Erotic Store","terms":"sex,porn"},"shop/fabric":{"name":"Fabric Store","terms":"sew"},"shop/farm":{"name":"Produce Stand","terms":"farm shop,farm stand"},"shop/fashion":{"name":"Fashion Store","terms":""},"shop/florist":{"name":"Florist","terms":"flower"},"shop/frame":{"name":"Framing Shop","terms":"art*,paint*,photo*,frame"},"shop/funeral_directors":{"name":"Funeral Home","terms":"undertaker,memorial home"},"shop/furnace":{"name":"Furnace Store","terms":"oven,stove"},"shop/furniture":{"name":"Furniture Store","terms":"chair,sofa,table"},"shop/garden_centre":{"name":"Garden Center","terms":"landscape,mulch,shrub,tree"},"shop/gift":{"name":"Gift Shop","terms":"souvenir"},"shop/greengrocer":{"name":"Greengrocer","terms":"fruit,vegetable"},"shop/hairdresser":{"name":"Hairdresser","terms":"barber"},"shop/hardware":{"name":"Hardware Store","terms":""},"shop/hearing_aids":{"name":"Hearing Aids Store","terms":""},"shop/herbalist":{"name":"Herbalist","terms":""},"shop/hifi":{"name":"Hifi Store","terms":"stereo,video"},"shop/houseware":{"name":"Houseware Store","terms":"home,household"},"shop/interior_decoration":{"name":"Interior Decoration Store","terms":""},"shop/jewelry":{"name":"Jeweler","terms":"diamond,gem,ring"},"shop/kiosk":{"name":"News Kiosk","terms":""},"shop/kitchen":{"name":"Kitchen Design Store","terms":""},"shop/laundry":{"name":"Laundry","terms":""},"shop/leather":{"name":"Leather Store","terms":""},"shop/locksmith":{"name":"Locksmith","terms":"key,lockpick"},"shop/lottery":{"name":"Lottery Shop","terms":""},"shop/mall":{"name":"Mall","terms":"shopping"},"shop/massage":{"name":"Massage Shop","terms":""},"shop/medical_supply":{"name":"Medical Supply Store","terms":""},"shop/mobile_phone":{"name":"Mobile Phone Store","terms":""},"shop/money_lender":{"name":"Money Lender","terms":""},"shop/motorcycle":{"name":"Motorcycle Dealership","terms":"bike"},"shop/music":{"name":"Music Store","terms":"CD,vinyl"},"shop/musical_instrument":{"name":"Musical Instrument Store","terms":"guitar"},"shop/newsagent":{"name":"Newspaper/Magazine Shop","terms":""},"shop/nutrition_supplements":{"name":"Nutrition Supplements Store","terms":""},"shop/optician":{"name":"Optician","terms":"eye,glasses"},"shop/organic":{"name":"Organic Goods Store","terms":""},"shop/outdoor":{"name":"Outdoors Store","terms":"camping,climbing,hiking"},"shop/paint":{"name":"Paint Store","terms":""},"shop/pastry":{"name":"Pastry Shop","terms":"patisserie,cake shop,cakery"},"shop/pawnbroker":{"name":"Pawn Shop","terms":""},"shop/pet":{"name":"Pet Store","terms":"cat,dog,fish"},"shop/photo":{"name":"Photography Store","terms":"camera,film"},"shop/pyrotechnics":{"name":"Fireworks Store","terms":""},"shop/radiotechnics":{"name":"Radio/Electronic Component Store","terms":""},"shop/religion":{"name":"Religious Store","terms":""},"shop/scuba_diving":{"name":"Scuba Diving Shop","terms":""},"shop/seafood":{"name":"Seafood Shop","terms":"fishmonger"},"shop/second_hand":{"name":"Consignment/Thrift Store","terms":"secondhand,second hand,resale,thrift,used"},"shop/shoes":{"name":"Shoe Store","terms":""},"shop/sports":{"name":"Sporting Goods Store","terms":""},"shop/stationery":{"name":"Stationery Store","terms":"card,paper"},"shop/storage_rental":{"name":"Storage Rental","terms":""},"shop/supermarket":{"name":"Supermarket","terms":"grocery,store,shop"},"shop/tailor":{"name":"Tailor","terms":"clothes,suit"},"shop/tattoo":{"name":"Tattoo Parlor","terms":""},"shop/tea":{"name":"Tea Store","terms":""},"shop/ticket":{"name":"Ticket Seller","terms":""},"shop/tobacco":{"name":"Tobacco Shop","terms":""},"shop/toys":{"name":"Toy Store","terms":""},"shop/travel_agency":{"name":"Travel Agency","terms":""},"shop/tyres":{"name":"Tire Store","terms":""},"shop/vacuum_cleaner":{"name":"Vacuum Cleaner Store","terms":""},"shop/variety_store":{"name":"Variety Store","terms":""},"shop/video_games":{"name":"Video Game Store","terms":""},"shop/video":{"name":"Video Store","terms":"DVD"},"shop/water_sports":{"name":"Watersport/Swim Shop","terms":""},"shop/weapons":{"name":"Weapon Shop","terms":"ammo,gun,knife,knives"},"shop/window_blind":{"name":"Window Blind Store","terms":""},"shop/wine":{"name":"Wine Shop","terms":""},"tourism":{"name":"Tourism","terms":""},"tourism/alpine_hut":{"name":"Alpine Hut","terms":""},"tourism/apartment":{"name":"Guest Apartment / Condo","terms":""},"tourism/artwork":{"name":"Artwork","terms":"mural,sculpture,statue"},"tourism/attraction":{"name":"Tourist Attraction","terms":""},"tourism/camp_site":{"name":"Campground","terms":"tent,rv"},"tourism/caravan_site":{"name":"RV Park","terms":"Motor Home,Camper"},"tourism/chalet":{"name":"Chalet","terms":""},"tourism/gallery":{"name":"Art Gallery","terms":"art*,exhibit*,paint*,photo*,sculpt*"},"tourism/guest_house":{"name":"Guest House","terms":"B&B,Bed and Breakfast"},"tourism/hostel":{"name":"Hostel","terms":""},"tourism/hotel":{"name":"Hotel","terms":""},"tourism/information":{"name":"Information","terms":""},"tourism/information/board":{"name":"Information Board","terms":""},"tourism/information/guidepost":{"name":"Guidepost","terms":""},"tourism/information/map":{"name":"Map","terms":""},"tourism/information/office":{"name":"Tourist Information Office","terms":""},"tourism/motel":{"name":"Motel","terms":""},"tourism/museum":{"name":"Museum","terms":"art*,exhibit*,gallery,foundation,hall,institution,paint*,photo*,sculpt*"},"tourism/picnic_site":{"name":"Picnic Site","terms":"camp"},"tourism/theme_park":{"name":"Theme Park","terms":""},"tourism/viewpoint":{"name":"Viewpoint","terms":""},"tourism/zoo":{"name":"Zoo","terms":""},"traffic_calming":{"name":"Traffic Calming","terms":"bump,hump,slow,speed"},"traffic_calming/bump":{"name":"Speed Bump","terms":"hump,speed,slow"},"traffic_calming/chicane":{"name":"Traffic Chicane","terms":"driveway link,speed,slow"},"traffic_calming/choker":{"name":"Traffic Choker","terms":"speed,slow"},"traffic_calming/cushion":{"name":"Speed Cushion","terms":"bump,hump,speed,slow"},"traffic_calming/dip":{"name":"Dip","terms":"speed,slow"},"traffic_calming/hump":{"name":"Speed Hump","terms":"bump,speed,slow"},"traffic_calming/island":{"name":"Traffic Island","terms":"circle,roundabout,slow"},"traffic_calming/rumble_strip":{"name":"Rumble Strip","terms":"audible lines,sleeper lines,growlers"},"traffic_calming/table":{"name":"Raised Pedestrian Crossing","terms":"flat top,hump,speed,slow"},"type/multipolygon":{"name":"Multipolygon","terms":""},"type/boundary":{"name":"Boundary","terms":""},"type/boundary/administrative":{"name":"Administrative Boundary","terms":""},"type/restriction":{"name":"Restriction","terms":""},"type/restriction/no_left_turn":{"name":"No Left Turn","terms":""},"type/restriction/no_right_turn":{"name":"No Right Turn","terms":""},"type/restriction/no_straight_on":{"name":"No Straight On","terms":""},"type/restriction/no_u_turn":{"name":"No U-turn","terms":""},"type/restriction/only_left_turn":{"name":"Left Turn Only","terms":""},"type/restriction/only_right_turn":{"name":"Right Turn Only","terms":""},"type/restriction/only_straight_on":{"name":"No Turns","terms":""},"type/route_master":{"name":"Route Master","terms":""},"type/route":{"name":"Route","terms":""},"type/route/bicycle":{"name":"Cycle Route","terms":""},"type/route/bus":{"name":"Bus Route","terms":""},"type/route/detour":{"name":"Detour Route","terms":""},"type/route/ferry":{"name":"Ferry Route","terms":""},"type/route/foot":{"name":"Foot Route","terms":""},"type/route/hiking":{"name":"Hiking Route","terms":""},"type/route/horse":{"name":"Riding Route","terms":""},"type/route/pipeline":{"name":"Pipeline Route","terms":""},"type/route/power":{"name":"Power Route","terms":""},"type/route/road":{"name":"Road Route","terms":""},"type/route/train":{"name":"Train Route","terms":""},"type/route/tram":{"name":"Tram Route","terms":""},"type/site":{"name":"Site","terms":""},"vertex":{"name":"Other","terms":""},"waterway/boatyard":{"name":"Boatyard","terms":""},"waterway/canal":{"name":"Canal","terms":""},"waterway/dam":{"name":"Dam","terms":""},"waterway/ditch":{"name":"Ditch","terms":""},"waterway/dock":{"name":"Wet Dock / Dry Dock","terms":"boat,ship,vessel,marine"},"waterway/drain":{"name":"Drain","terms":""},"waterway/fuel":{"name":"Marine Fuel Station","terms":"petrol,gas,diesel,boat"},"waterway/river":{"name":"River","terms":"beck,branch,brook,course,creek,estuary,rill,rivulet,run,runnel,stream,tributary,watercourse"},"waterway/riverbank":{"name":"Riverbank","terms":""},"waterway/sanitary_dump_station":{"name":"Marine Toilet Disposal","terms":"Boat,Watercraft,Sanitary,Dump Station,Pumpout,Pump out,Elsan,CDP,CTDP,Chemical Toilet"},"waterway/stream":{"name":"Stream","terms":"beck,branch,brook,burn,course,creek,current,drift,flood,flow,freshet,race,rill,rindle,rivulet,run,runnel,rush,spate,spritz,surge,tide,torrent,tributary,watercourse"},"waterway/water_point":{"name":"Marine Drinking Water","terms":""},"waterway/weir":{"name":"Weir","terms":""}}}};
18960 var dataImagery = [{"id":"sjcgis.org-Aerials_2013_WM","name":"2013 aerial imagery for San Juan County WA","type":"tms","template":"http://sjcgis.org/arcgis/rest/services/Basemaps/Aerials_2013_WM/MapServer/tile/{zoom}/{y}/{x}","description":"Public domain aerial imagery taken in May/June 2013 from San Juan County, WA. Resolution is 9 inch.","scaleExtent":[0,19],"polygon":[[[-123.274024,48.692975],[-123.007726,48.767256],[-123.007619,48.831577],[-122.783495,48.758416],[-122.693402,48.658522],[-122.767451,48.603606],[-122.744842,48.387083],[-123.248221,48.283531],[-123.114524,48.422614],[-123.219035,48.548575],[-123.274024,48.692975]]],"best":true},{"id":"OS7","name":"7th Series (OS7)","type":"tms","template":"http://ooc.openstreetmap.org/os7/{zoom}/{x}/{y}.jpg","polygon":[[[-9,49.8],[-9,61.1],[1.9,61.1],[1.9,49.8],[-9,49.8]]]},{"id":"AGRI-black_and_white-2.5m","name":"AGRI black-and-white 2.5m","type":"tms","template":"http://agri.openstreetmap.org/{zoom}/{x}/{y}.png","polygon":[[[112.28778,-28.784589],[112.71488,-31.13894],[114.11263,-34.178287],[113.60788,-37.39012],[117.17992,-37.451794],[119.31538,-37.42096],[121.72262,-36.708394],[123.81925,-35.76893],[125.9547,-34.3066],[127.97368,-33.727398],[130.07031,-33.24166],[130.10913,-33.888704],[131.00214,-34.049705],[131.0798,-34.72257],[132.28342,-35.39],[134.18591,-35.61126],[133.8753,-37.1119],[134.8459,-37.6365],[139.7769,-37.82075],[139.93223,-39.4283],[141.6017,-39.8767],[142.3783,-39.368294],[142.3783,-40.64702],[142.49478,-42.074874],[144.009,-44.060127],[147.23161,-44.03222],[149.05645,-42.534313],[149.52237,-40.99959],[149.9494,-40.852921],[150.8036,-38.09627],[151.81313,-38.12682],[156.20052,-22.667706],[156.20052,-20.10109],[156.62761,-17.417627],[155.26869,-17.19521],[154.14272,-19.51662],[153.5215,-18.34139],[153.05558,-16.5636],[152.78379,-15.256768],[152.27905,-13.4135],[151.3472,-12.391767],[149.48354,-12.05024],[146.9598,-9.992408],[135.9719,-9.992408],[130.3032,-10.33636],[128.09016,-12.164136],[125.91588,-12.315912],[124.3239,-11.860326],[122.03323,-11.974295],[118.26706,-16.9353],[115.93747,-19.11357],[114.0738,-21.11863],[113.49141,-22.596033],[112.28778,-28.784589]]],"terms_text":"AGRI"},{"id":"basemap.at","name":"basemap.at","type":"tms","template":"https://maps{switch:1,2,3,4}.wien.gv.at/basemap/geolandbasemap/normal/google3857/{zoom}/{y}/{x}.png","description":"Basemap of Austria, based on goverment data.","polygon":[[[16.5073284,46.9929304],[16.283417,46.9929304],[16.135839,46.8713046],[15.9831722,46.8190947],[16.0493278,46.655175],[15.8610387,46.7180116],[15.7592608,46.6900933],[15.5607938,46.6796202],[15.5760605,46.6342132],[15.4793715,46.6027553],[15.4335715,46.6516819],[15.2249267,46.6342132],[15.0468154,46.6481886],[14.9908376,46.5887681],[14.9603042,46.6237293],[14.8534374,46.6027553],[14.8330818,46.5012666],[14.7516595,46.4977636],[14.6804149,46.4381781],[14.6142593,46.4381781],[14.578637,46.3785275],[14.4412369,46.4311638],[14.1613476,46.4276563],[14.1257253,46.4767409],[14.0188585,46.4767409],[13.9119917,46.5257813],[13.8254805,46.5047694],[13.4438134,46.560783],[13.3064132,46.5502848],[13.1283019,46.5887681],[12.8433237,46.6132433],[12.7262791,46.6412014],[12.5125455,46.6656529],[12.3598787,46.7040543],[12.3649676,46.7703197],[12.2886341,46.7772902],[12.2733674,46.8852187],[12.2072118,46.8747835],[12.1308784,46.9026062],[12.1156117,46.9998721],[12.2530119,47.0657733],[12.2123007,47.0934969],[11.9833004,47.0449712],[11.7339445,46.9616816],[11.6321666,47.010283],[11.5405665,46.9755722],[11.4998553,47.0068129],[11.418433,46.9651546],[11.2555884,46.9755722],[11.1130993,46.913036],[11.0418548,46.7633482],[10.8891879,46.7598621],[10.7416099,46.7842599],[10.7059877,46.8643462],[10.5787653,46.8399847],[10.4566318,46.8504267],[10.4769874,46.9269392],[10.3853873,46.9894592],[10.2327204,46.8643462],[10.1207647,46.8330223],[9.8663199,46.9408389],[9.9019422,47.0033426],[9.6831197,47.0588402],[9.6118752,47.0380354],[9.6322307,47.128131],[9.5813418,47.1662025],[9.5406306,47.2664422],[9.6067863,47.3492559],[9.6729419,47.369939],[9.6424085,47.4457079],[9.5660751,47.4801122],[9.7136531,47.5282405],[9.7848976,47.5969187],[9.8357866,47.5454185],[9.9477423,47.538548],[10.0902313,47.4491493],[10.1105869,47.3664924],[10.2428982,47.3871688],[10.1869203,47.2698953],[10.3243205,47.2975125],[10.4820763,47.4491493],[10.4311873,47.4869904],[10.4413651,47.5900549],[10.4871652,47.5522881],[10.5482319,47.5351124],[10.5991209,47.5660246],[10.7568766,47.5316766],[10.8891879,47.5454185],[10.9400769,47.4869904],[10.9960547,47.3906141],[11.2352328,47.4422662],[11.2810328,47.3975039],[11.4235219,47.5144941],[11.5761888,47.5076195],[11.6067221,47.5900549],[11.8357224,47.5866227],[12.003656,47.6243647],[12.2072118,47.6037815],[12.1614117,47.6963421],[12.2581008,47.7442718],[12.2530119,47.6792136],[12.4311232,47.7100408],[12.4921899,47.631224],[12.5685234,47.6277944],[12.6295901,47.6894913],[12.7720792,47.6689338],[12.8331459,47.5419833],[12.975635,47.4732332],[13.0417906,47.4938677],[13.0367017,47.5557226],[13.0977685,47.6415112],[13.0316128,47.7100408],[12.9043905,47.7203125],[13.0061684,47.84683],[12.9451016,47.9355501],[12.8636793,47.9594103],[12.8636793,48.0036929],[12.7517236,48.0989418],[12.8738571,48.2109733],[12.9603683,48.2109733],[13.0417906,48.2652035],[13.1842797,48.2990682],[13.2606131,48.2922971],[13.3980133,48.3565867],[13.4438134,48.417418],[13.4387245,48.5523383],[13.509969,48.5860123],[13.6117469,48.5725454],[13.7287915,48.5118999],[13.7847694,48.5725454],[13.8203916,48.6263915],[13.7949471,48.7171267],[13.850925,48.7741724],[14.0595697,48.6633774],[14.0137696,48.6331182],[14.0748364,48.5927444],[14.2173255,48.5961101],[14.3649034,48.5489696],[14.4666813,48.6499311],[14.5582815,48.5961101],[14.5989926,48.6263915],[14.7211261,48.5759124],[14.7211261,48.6868997],[14.822904,48.7271983],[14.8178151,48.777526],[14.9647227,48.7851754],[14.9893637,49.0126611],[15.1485933,48.9950306],[15.1943934,48.9315502],[15.3063491,48.9850128],[15.3928603,48.9850128],[15.4844604,48.9282069],[15.749083,48.8545973],[15.8406831,48.8880697],[16.0086166,48.7808794],[16.2070835,48.7339115],[16.3953727,48.7372678],[16.4920617,48.8110498],[16.6905286,48.7741724],[16.7057953,48.7339115],[16.8991733,48.713769],[16.9755067,48.515271],[16.8482844,48.4511817],[16.8533733,48.3464411],[16.9551512,48.2516513],[16.9907734,48.1498955],[17.0925513,48.1397088],[17.0823736,48.0241182],[17.1739737,48.0207146],[17.0823736,47.8741447],[16.9856845,47.8673174],[17.0823736,47.8092489],[17.0925513,47.7031919],[16.7414176,47.6792136],[16.7057953,47.7511153],[16.5378617,47.7545368],[16.5480395,47.7066164],[16.4208172,47.6689338],[16.573484,47.6175045],[16.670173,47.631224],[16.7108842,47.538548],[16.6599952,47.4491493],[16.5429506,47.3940591],[16.4615283,47.3940591],[16.4920617,47.276801],[16.425906,47.1973317],[16.4717061,47.1489007],[16.5480395,47.1489007],[16.476795,47.0796369],[16.527684,47.0588402],[16.5073284,46.9929304]]],"terms_text":"basemap.at"},{"id":"basemap.at-orthofoto","name":"basemap.at Orthofoto","type":"tms","template":"https://maps{switch:1,2,3,4}.wien.gv.at/basemap/bmaporthofoto30cm/normal/google3857/{zoom}/{y}/{x}.jpeg","description":"Orthofoto layer provided by basemap.at. \"Successor\" of geoimage.at imagery.","polygon":[[[16.5073284,46.9929304],[16.283417,46.9929304],[16.135839,46.8713046],[15.9831722,46.8190947],[16.0493278,46.655175],[15.8610387,46.7180116],[15.7592608,46.6900933],[15.5607938,46.6796202],[15.5760605,46.6342132],[15.4793715,46.6027553],[15.4335715,46.6516819],[15.2249267,46.6342132],[15.0468154,46.6481886],[14.9908376,46.5887681],[14.9603042,46.6237293],[14.8534374,46.6027553],[14.8330818,46.5012666],[14.7516595,46.4977636],[14.6804149,46.4381781],[14.6142593,46.4381781],[14.578637,46.3785275],[14.4412369,46.4311638],[14.1613476,46.4276563],[14.1257253,46.4767409],[14.0188585,46.4767409],[13.9119917,46.5257813],[13.8254805,46.5047694],[13.4438134,46.560783],[13.3064132,46.5502848],[13.1283019,46.5887681],[12.8433237,46.6132433],[12.7262791,46.6412014],[12.5125455,46.6656529],[12.3598787,46.7040543],[12.3649676,46.7703197],[12.2886341,46.7772902],[12.2733674,46.8852187],[12.2072118,46.8747835],[12.1308784,46.9026062],[12.1156117,46.9998721],[12.2530119,47.0657733],[12.2123007,47.0934969],[11.9833004,47.0449712],[11.7339445,46.9616816],[11.6321666,47.010283],[11.5405665,46.9755722],[11.4998553,47.0068129],[11.418433,46.9651546],[11.2555884,46.9755722],[11.1130993,46.913036],[11.0418548,46.7633482],[10.8891879,46.7598621],[10.7416099,46.7842599],[10.7059877,46.8643462],[10.5787653,46.8399847],[10.4566318,46.8504267],[10.4769874,46.9269392],[10.3853873,46.9894592],[10.2327204,46.8643462],[10.1207647,46.8330223],[9.8663199,46.9408389],[9.9019422,47.0033426],[9.6831197,47.0588402],[9.6118752,47.0380354],[9.6322307,47.128131],[9.5813418,47.1662025],[9.5406306,47.2664422],[9.6067863,47.3492559],[9.6729419,47.369939],[9.6424085,47.4457079],[9.5660751,47.4801122],[9.7136531,47.5282405],[9.7848976,47.5969187],[9.8357866,47.5454185],[9.9477423,47.538548],[10.0902313,47.4491493],[10.1105869,47.3664924],[10.2428982,47.3871688],[10.1869203,47.2698953],[10.3243205,47.2975125],[10.4820763,47.4491493],[10.4311873,47.4869904],[10.4413651,47.5900549],[10.4871652,47.5522881],[10.5482319,47.5351124],[10.5991209,47.5660246],[10.7568766,47.5316766],[10.8891879,47.5454185],[10.9400769,47.4869904],[10.9960547,47.3906141],[11.2352328,47.4422662],[11.2810328,47.3975039],[11.4235219,47.5144941],[11.5761888,47.5076195],[11.6067221,47.5900549],[11.8357224,47.5866227],[12.003656,47.6243647],[12.2072118,47.6037815],[12.1614117,47.6963421],[12.2581008,47.7442718],[12.2530119,47.6792136],[12.4311232,47.7100408],[12.4921899,47.631224],[12.5685234,47.6277944],[12.6295901,47.6894913],[12.7720792,47.6689338],[12.8331459,47.5419833],[12.975635,47.4732332],[13.0417906,47.4938677],[13.0367017,47.5557226],[13.0977685,47.6415112],[13.0316128,47.7100408],[12.9043905,47.7203125],[13.0061684,47.84683],[12.9451016,47.9355501],[12.8636793,47.9594103],[12.8636793,48.0036929],[12.7517236,48.0989418],[12.8738571,48.2109733],[12.9603683,48.2109733],[13.0417906,48.2652035],[13.1842797,48.2990682],[13.2606131,48.2922971],[13.3980133,48.3565867],[13.4438134,48.417418],[13.4387245,48.5523383],[13.509969,48.5860123],[13.6117469,48.5725454],[13.7287915,48.5118999],[13.7847694,48.5725454],[13.8203916,48.6263915],[13.7949471,48.7171267],[13.850925,48.7741724],[14.0595697,48.6633774],[14.0137696,48.6331182],[14.0748364,48.5927444],[14.2173255,48.5961101],[14.3649034,48.5489696],[14.4666813,48.6499311],[14.5582815,48.5961101],[14.5989926,48.6263915],[14.7211261,48.5759124],[14.7211261,48.6868997],[14.822904,48.7271983],[14.8178151,48.777526],[14.9647227,48.7851754],[14.9893637,49.0126611],[15.1485933,48.9950306],[15.1943934,48.9315502],[15.3063491,48.9850128],[15.3928603,48.9850128],[15.4844604,48.9282069],[15.749083,48.8545973],[15.8406831,48.8880697],[16.0086166,48.7808794],[16.2070835,48.7339115],[16.3953727,48.7372678],[16.4920617,48.8110498],[16.6905286,48.7741724],[16.7057953,48.7339115],[16.8991733,48.713769],[16.9755067,48.515271],[16.8482844,48.4511817],[16.8533733,48.3464411],[16.9551512,48.2516513],[16.9907734,48.1498955],[17.0925513,48.1397088],[17.0823736,48.0241182],[17.1739737,48.0207146],[17.0823736,47.8741447],[16.9856845,47.8673174],[17.0823736,47.8092489],[17.0925513,47.7031919],[16.7414176,47.6792136],[16.7057953,47.7511153],[16.5378617,47.7545368],[16.5480395,47.7066164],[16.4208172,47.6689338],[16.573484,47.6175045],[16.670173,47.631224],[16.7108842,47.538548],[16.6599952,47.4491493],[16.5429506,47.3940591],[16.4615283,47.3940591],[16.4920617,47.276801],[16.425906,47.1973317],[16.4717061,47.1489007],[16.5480395,47.1489007],[16.476795,47.0796369],[16.527684,47.0588402],[16.5073284,46.9929304]]],"terms_text":"basemap.at","best":true},{"id":"bavaria-DOP80","name":"Bavaria DOP 80cm","type":"tms","template":"http://mapproxy.osm.ch:8080/tiles/BAYERNDOP80/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","scaleExtent":[0,18],"polygon":[[[10.1235886,50.568462],[10.1428576,50.5507804],[10.2028056,50.5574195],[10.2520485,50.5179575],[10.3269835,50.4934473],[10.4104825,50.4184762],[10.6031724,50.3310874],[10.6224414,50.2271041],[10.7252093,50.2106649],[10.7294913,50.2476451],[10.8515282,50.2435376],[10.7187863,50.3201525],[10.7123633,50.3652428],[10.8558102,50.3966441],[10.9371682,50.3966441],[10.9906932,50.3666085],[11.1277171,50.3666085],[11.1791011,50.3133169],[11.1619731,50.294172],[11.24119,50.2928042],[11.249754,50.3734364],[11.24119,50.479825],[11.358945,50.5234025],[11.4381619,50.5097889],[11.4424439,50.4893611],[11.425316,50.4771001],[11.425316,50.4416618],[11.4895459,50.4225686],[11.4916869,50.3980089],[11.5195199,50.3980089],[11.5259429,50.3761673],[11.5987369,50.4034677],[11.6372748,50.3884544],[11.7935678,50.4212045],[11.8363877,50.3925494],[11.9220277,50.4280246],[11.9862577,50.3870894],[11.9841167,50.3570478],[12.0483466,50.3310874],[12.0933076,50.3297207],[12.1297046,50.2982751],[12.1404096,50.2722826],[12.1061536,50.255859],[12.1125766,50.2353216],[12.1489736,50.236691],[12.1982166,50.2010728],[12.2239086,50.1640565],[12.2046396,50.1434795],[12.2067806,50.1077916],[12.2431775,50.0995522],[12.2774335,50.0720772],[12.4936744,49.985428],[12.4979564,49.9413559],[12.5557634,49.9220616],[12.5493404,49.8682726],[12.4808284,49.7881677],[12.4101755,49.7577484],[12.4615594,49.7065456],[12.5471994,49.6802313],[12.5878784,49.552613],[12.6542493,49.534553],[12.6628133,49.4330153],[12.7527353,49.4107323],[12.7976963,49.3466124],[12.9047462,49.3563752],[12.9968092,49.3368477],[13.0546161,49.2754251],[13.1316921,49.2195199],[13.1916401,49.1439475],[13.236601,49.1215335],[13.296549,49.1229347],[13.371484,49.0808823],[13.414304,49.0289687],[13.414304,48.9798112],[13.5791609,48.9699739],[13.6348268,48.9432629],[13.6776468,48.8869823],[13.7375948,48.8926132],[13.7846968,48.8334571],[13.8403627,48.774231],[13.8168118,48.7064584],[13.8446447,48.7008065],[13.8425037,48.6003807],[13.7654278,48.5422972],[13.7525818,48.5040106],[13.6712238,48.5054291],[13.6433908,48.5437146],[13.4571239,48.5508013],[13.4571239,48.4159838],[13.40574,48.3605338],[13.283703,48.2751083],[13.0931541,48.2694081],[12.9582712,48.1909669],[12.8769132,48.1852574],[12.7720043,48.0938188],[12.8640672,48.0136764],[12.8983232,47.9549216],[12.9454252,47.9563555],[12.9968092,47.8846147],[13.0139372,47.834337],[12.9347202,47.7321953],[13.0588981,47.7249947],[13.1188461,47.6385093],[13.0653211,47.5692178],[13.0567571,47.473792],[13.0032322,47.4520801],[12.7677223,47.5504355],[12.7698633,47.6327385],[12.7398893,47.6731207],[12.6670953,47.6702373],[12.5750324,47.621195],[12.4808284,47.6197519],[12.4144575,47.6702373],[12.2431775,47.6774455],[12.2132036,47.6918589],[12.1917936,47.6817699],[12.2132036,47.6659119],[12.2110626,47.603875],[12.1746656,47.5952129],[12.1382686,47.603875],[11.8920537,47.603875],[11.8513747,47.5793285],[11.6394158,47.5822169],[11.5944549,47.5489905],[11.5901729,47.5128508],[11.5173789,47.498388],[11.4403029,47.5041736],[11.395342,47.4752392],[11.427457,47.4448409],[11.346099,47.4433929],[11.279728,47.3955873],[11.2133571,47.3883402],[11.247613,47.4318076],[11.1020251,47.3926886],[10.9650012,47.3897897],[10.9778472,47.4361524],[10.9178992,47.4752392],[10.8707972,47.4752392],[10.8558102,47.4940484],[10.9007712,47.5142969],[10.8729382,47.5359831],[10.8108493,47.5128508],[10.6438513,47.5489905],[10.5946084,47.5547705],[10.5796214,47.5287553],[10.4618664,47.5403192],[10.4661484,47.4839212],[10.4875584,47.4781333],[10.4875584,47.4129762],[10.4597254,47.4028333],[10.4597254,47.375293],[10.4104825,47.3738431],[10.4083415,47.3433862],[10.3205605,47.2867768],[10.2820225,47.2780622],[10.2841635,47.2620819],[10.1471396,47.2620819],[10.1921006,47.3027497],[10.1942416,47.3738431],[10.1664086,47.3738431],[10.1664086,47.3462876],[10.1000376,47.3433862],[10.0614996,47.3636928],[10.0679226,47.4187712],[10.0936146,47.426014],[10.0957556,47.4419449],[9.9780007,47.485368],[9.9565907,47.5273097],[9.8945017,47.5287553],[9.8559637,47.5085124],[9.8174258,47.544655],[9.8217078,47.5764399],[9.7746058,47.5822169],[9.7382088,47.525864],[9.6739788,47.5345376],[9.5840569,47.564884],[9.6397228,47.6053186],[9.7167988,47.603875],[9.8559637,47.6760039],[9.9780007,47.6558179],[10.0293846,47.6817699],[10.1000376,47.6673537],[10.1321526,47.6760039],[10.1428576,47.7019459],[10.0614996,47.7725005],[10.1128836,47.8098988],[10.0829096,47.8530173],[10.1086016,47.9090177],[10.0764866,47.9649577],[10.1300116,48.020837],[10.1342936,48.1066872],[10.1000376,48.1281274],[10.0550766,48.2622821],[9.9694367,48.3676462],[10.0315256,48.4259299],[10.0293846,48.461436],[10.1235886,48.4770509],[10.1535626,48.4514968],[10.2349205,48.5125212],[10.3162785,48.516776],[10.2991505,48.6187835],[10.2456255,48.6682961],[10.2734585,48.7064584],[10.3698035,48.6838472],[10.4318924,48.6993935],[10.4511614,48.7276471],[10.4019185,48.7460035],[10.4404564,48.8489571],[10.4340334,48.9587289],[10.3376885,49.0205451],[10.2499075,49.0359872],[10.2499075,49.0738701],[10.2006646,49.1033147],[10.2520485,49.1327418],[10.1235886,49.1971401],[10.1193066,49.2628519],[10.1514216,49.2893915],[10.1043196,49.3452175],[10.1407166,49.3940134],[10.1086016,49.445545],[10.1107426,49.5053651],[10.0722046,49.5331635],[10.0165387,49.4761598],[9.9266167,49.478942],[9.9244757,49.5567797],[9.8987837,49.5817727],[9.8559637,49.5387213],[9.8067208,49.5567797],[9.8666687,49.6067529],[9.8538227,49.6441991],[9.8174258,49.6608327],[9.8345537,49.6899277],[9.7960158,49.7203895],[9.7574778,49.7079302],[9.7403498,49.6857723],[9.7060938,49.7162368],[9.6782608,49.7162368],[9.6825428,49.6885426],[9.6204539,49.6913127],[9.6461458,49.78955],[9.5583649,49.7743431],[9.5712109,49.7356133],[9.5069809,49.7522156],[9.4919939,49.7798735],[9.4684429,49.7605146],[9.425623,49.7784909],[9.404213,49.7646636],[9.33356,49.770195],[9.329278,49.7342295],[9.408495,49.725926],[9.427764,49.6982374],[9.414918,49.6441991],[9.380662,49.6386533],[9.359252,49.6497443],[9.339983,49.6372668],[9.31215,49.648358],[9.277894,49.626173],[9.284317,49.6081403],[9.241497,49.5748315],[9.0980501,49.5720547],[9.0659351,49.6081403],[9.1001911,49.6511305],[9.0916271,49.6926978],[9.1301651,49.7120837],[9.1387291,49.7425316],[9.1087551,49.7563653],[9.1365881,49.7909322],[9.1001911,49.78955],[9.0723581,49.8282367],[9.0359611,49.8351418],[9.0166922,50.0267091],[8.9631672,50.0308352],[8.9567442,50.0597083],[9.0017052,50.0707031],[9.0209742,50.1105378],[9.1216011,50.1228936],[9.1558571,50.1132838],[9.1965361,50.1187753],[9.1858311,50.1352462],[9.235074,50.1475956],[9.37638,50.1270115],[9.408495,50.0816953],[9.5219679,50.095432],[9.5048399,50.1421073],[9.5326729,50.1640565],[9.4898529,50.1695422],[9.4941349,50.2435376],[9.6140309,50.221625],[9.6654148,50.2353216],[9.6354408,50.2490142],[9.6675558,50.2722826],[9.7424908,50.3092151],[9.7296448,50.3584137],[9.7703238,50.4293885],[9.8688097,50.4007384],[9.9180527,50.4089259],[10.0358076,50.479825],[10.0379486,50.5111504],[10.1235886,50.568462]]]},{"id":"AGIV","name":"Belgium AGIV Orthophoto Flanders","type":"tms","template":"http://tile.informatievlaanderen.be/ws/raadpleegdiensten/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=omwrgbmrvl&STYLE=&FORMAT=image/png&tileMatrixSet=GoogleMapsVL&tileMatrix={zoom}&tileRow={y}&tileCol={x}","scaleExtent":[0,21],"polygon":[[[2.522393220658428,51.101723961331],[3.1260610915867457,51.34117672029327],[3.174929443042849,51.382459567439525],[3.3761520666856217,51.38784154353026],[3.410647373595811,51.33040116175589],[3.4020235468682634,51.28547573497245],[3.4911364230529203,51.256700377228974],[3.4825125963253734,51.30345118353617],[3.5773746903283947,51.323216048914524],[3.813092620881357,51.27288873325703],[3.8217164476089045,51.236906864834886],[3.9309515861578386,51.236906864834886],[4.054559769252684,51.27468708752057],[4.20116482362099,51.35194974615148],[4.169544125619984,51.38066543475199],[4.342020660170932,51.395016527087456],[4.3650175314443915,51.46491366130351],[4.5374940659953396,51.50071687469512],[4.571989372905529,51.479238319799464],[4.560490937268798,51.44879304380801],[4.638105377816725,51.45058450468522],[4.750215125274841,51.5239738914927],[4.8364533925503155,51.507874144493115],[5.080795149830825,51.49892738159079],[5.135412719105292,51.447001512638565],[5.106666630013469,51.391429175957505],[5.264770120018504,51.31782647548482],[5.264770120018504,51.28727359653538],[5.4085005654776275,51.292666758936925],[5.486115006025553,51.325012432665545],[5.5809771000285755,51.28367780302667],[5.583851708937758,51.23510703218069],[5.767826679125435,51.20449910348059],[5.8770618176743685,51.161253258857485],[5.704585283123422,50.80292546633848],[5.905807906766195,50.7865720955422],[5.9374286047672005,50.732019528192964],[5.902933297857012,50.70107817444857],[5.8138204216723555,50.69379488717487],[5.615472406938765,50.761122144578216],[5.500488050571466,50.71200098472672],[5.204403332925673,50.70289881954383],[5.164158808197117,50.67558172042608],[5.037676016193088,50.70107817444857],[4.988807664736986,50.750210783384084],[4.916942442007425,50.72656077355532],[4.790459650003396,50.766576871275696],[4.681224511454462,50.77021300246129],[4.6697260758177315,50.73565834458533],[4.287403090896464,50.67922491935501],[3.91082932379356,50.677403355240585],[3.718230526878334,50.752029520237265],[3.6549891308763196,50.71200098472672],[3.5342555566906557,50.710180693059606],[3.514133294326379,50.741116039142966],[3.45664111614273,50.74384464791457],[3.373277457776438,50.69561581502901],[3.310036061774423,50.70745012302645],[3.2899137994101473,50.7365680045137],[3.1648683118607086,50.742935129324266],[3.1318103094051106,50.77203096207303],[3.080067349039826,50.76021296163662],[2.8745328120332805,50.73929687829333],[2.8960923788521487,50.71109084772858],[2.8745328120332805,50.69561581502901],[2.796918371485353,50.70289881954383],[2.699181668573149,50.80020030189157],[2.6201299235706315,50.79747497850781],[2.5698242676599374,50.85830267681076],[2.5669496587507554,50.923581424665855],[2.6028822701155367,50.94984841176044],[2.549702005295661,50.996006093918574],[2.522393220658428,51.101723961331]]],"terms_text":"Orthophoto Flanders most recent (c) AGIV","best":true},{"id":"Benin_cotonou_pleiade_2016","name":"Benin: Cotonou Pleiade 2016","type":"tms","template":"http://geoxxx.agrocampus-ouest.fr/owsifl/gwc/service/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=Benin:cotonou_pleiade_2016&STYLE=&FORMAT=image/jpeg&tileMatrixSet=EPSG:3857&tileMatrix=EPSG:3857:{zoom}&tileRow={y}&tileCol={x}","scaleExtent":[0,21],"polygon":[[[2.31953818544,6.55745092536],[2.33645249928,6.56023631702],[2.36377172444,6.56211241002],[2.36737717181,6.56067658005],[2.37777373205,6.54939665325],[2.3777926612,6.53484752744],[2.36994151563,6.4933195729],[2.37038356708,6.45527010853],[2.36958186167,6.45269435578],[2.36188103586,6.44177160245],[2.35391742884,6.40545220189],[2.3674929737,6.40149524022],[2.39525870424,6.40071623744],[2.40128040262,6.40374371884],[2.40587684694,6.40340733291],[2.42045897749,6.39382909301],[2.42485054154,6.3979366042],[2.42949152505,6.39887495342],[2.43625257397,6.39628121034],[2.43958410532,6.40041525877],[2.44439433776,6.40189359345],[2.45375647532,6.39899446003],[2.47144744127,6.3963166199],[2.48162019208,6.3910582748],[2.49453210303,6.38739776192],[2.50893162289,6.38888498676],[2.50719014059,6.39228876781],[2.50120407357,6.39162040687],[2.4963025358,6.39521449649],[2.49509997769,6.40123077776],[2.49543290813,6.40400928653],[2.49830345887,6.41022131795],[2.50191336015,6.41281720321],[2.5108701911,6.41321333458],[2.52218648559,6.40849403999],[2.53352059576,6.4051656109],[2.53809922441,6.40960941297],[2.5411100736,6.41090182623],[2.54650822333,6.41099034757],[2.54654385468,6.40651114868],[2.57638511144,6.40723702943],[2.57642074279,6.41176933466],[2.58575615684,6.41196408125],[2.58867792765,6.41095493903],[2.60877400982,6.39413560832],[2.62569890171,6.39487921149],[2.64554556441,6.39728706193],[2.65039142819,6.39339200408],[2.6536650586,6.36823275735],[2.6431181786,6.3665949733],[2.61251084779,6.3628944474],[2.56867983171,6.3607044406],[2.54682890549,6.36055393954],[2.54687344468,6.35546343647],[2.50206702036,6.35461353888],[2.47064016846,6.35595920942],[2.46777184468,6.35202842507],[2.46422652522,6.35020467258],[2.45253944198,6.35006302163],[2.4511320036,6.34813302357],[2.44737289603,6.34629155079],[2.43757427441,6.34653944174],[2.43297783009,6.33841209773],[2.43016295333,6.33706638135],[2.42244876576,6.33706638135],[2.39236031651,6.34114999999],[2.39315311407,6.34114999999],[2.3652849434,6.34445228474],[2.35386064137,6.34529777247],[2.34377474198,6.34457844399],[2.34093759563,6.34533982549],[2.31086028117,6.36567095094],[2.28434610184,6.37465215648],[2.28146887022,6.37761782314],[2.27599054995,6.39517244756],[2.27611525968,6.39819996182],[2.31528747657,6.4926104105],[2.31579967725,6.5530659484]],[[1.69563043958,6.25076170066],[1.70009994721,6.24711901182],[1.70417862346,6.24697179839],[1.75874803806,6.25835802546],[1.77079143482,6.25995187823],[1.81712109941,6.27161341959],[1.84456614779,6.27656750346],[1.85767848509,6.27944518918],[1.88843363033,6.28325588467],[1.90481876292,6.28594870029],[1.90617692982,6.29435189983],[1.90083111364,6.29721233234],[1.89880903445,6.29953873942],[1.89404334121,6.30085024405],[1.89047742238,6.29969866569],[1.88747882146,6.29636150888],[1.88344050885,6.29622344016],[1.86969682855,6.29226563906],[1.8564007671,6.29198230539],[1.85206654725,6.28674503171],[1.84991419093,6.28906373821],[1.84691224958,6.29202989661],[1.8435272712,6.29332703219],[1.84040507404,6.29315437611],[1.83626738336,6.29129499924],[1.83409832485,6.28733273348],[1.83416513363,6.2851988527],[1.83229560117,6.28456355663],[1.82785949792,6.28644177291],[1.82182443779,6.2908379014],[1.81562903657,6.28997904337],[1.81211044063,6.29143113241],[1.80757635117,6.29570768815],[1.80471693522,6.29692955475],[1.80073513171,6.29709778253],[1.79775991387,6.29612383144],[1.79625448928,6.29491967121],[1.79490049792,6.28965143736],[1.79641483036,6.28608317469],[1.80097564333,6.28338261222],[1.79566657198,6.28013306439],[1.79156005874,6.28174455931],[1.78498607441,6.28122215216],[1.78092410036,6.27752986974],[1.77588226414,6.27550220232],[1.76744654171,6.27696318619],[1.75653444036,6.27496207997],[1.74833032171,6.27238985028],[1.74761769468,6.27726423691],[1.74572477914,6.27938486862],[1.73948038482,6.27984972411],[1.73680357955,6.27761398678],[1.73572127725,6.27891558552],[1.72901812928,6.27911038233],[1.72435487617,6.27422273126],[1.72449294765,6.2678607472],[1.72555966124,6.26683029328],[1.69933944056,6.26159387355],[1.69572953928,6.25725948175]]],"best":true},{"id":"Bing","name":"Bing aerial imagery","type":"bing","template":"http://www.bing.com/maps/","description":"Satellite and aerial imagery.","scaleExtent":[0,22],"default":true},{"id":"British_Columbia_Mosaic","name":"British Columbia Mosaic","type":"tms","template":"http://{switch:a,b,c,d}.imagery.paulnorman.ca/tiles/bc_mosaic/{zoom}/{x}/{y}.png","scaleExtent":[9,20],"polygon":[[[-123.3176032,49.3272567],[-123.4405258,49.3268222],[-123.440717,49.3384429],[-123.4398375,49.3430357],[-123.4401258,49.3435398],[-123.4401106,49.3439946],[-123.4406265,49.3444493],[-123.4404747,49.3455762],[-123.4397768,49.3460606],[-123.4389726,49.3461298],[-123.4372904,49.3567236],[-123.4374774,49.3710843],[-123.4335292,49.3709446],[-123.4330357,49.373725],[-123.4332717,49.3751221],[-123.4322847,49.3761001],[-123.4317482,49.3791736],[-123.4314264,49.3795927],[-123.4307826,49.3823866],[-123.4313405,49.3827358],[-123.4312118,49.3838533],[-123.4300415,49.3845883],[-123.4189858,49.3847087],[-123.4192235,49.4135198],[-123.3972532,49.4135691],[-123.3972758,49.4243473],[-123.4006929,49.4243314],[-123.4007741,49.5703491],[-123.4000812,49.570345],[-123.4010761,49.5933838],[-123.3760399,49.5932848],[-123.3769811,49.6756063],[-123.3507288,49.6756396],[-123.3507969,49.7086751],[-123.332887,49.708722],[-123.3327888,49.7256288],[-123.3007111,49.7255625],[-123.3009164,49.7375384],[-123.2885986,49.737638],[-123.2887823,49.8249207],[-123.2997955,49.8249207],[-123.3011721,49.8497814],[-123.3218218,49.850669],[-123.3273284,49.8577696],[-123.3276726,49.9758852],[-123.3008279,49.9752212],[-123.3007204,50.0997002],[-123.2501716,50.100735],[-123.25091,50.2754901],[-123.0224338,50.2755598],[-123.0224879,50.3254853],[-123.0009318,50.3254689],[-123.0007778,50.3423899],[-122.9775023,50.3423408],[-122.9774766,50.3504306],[-122.9508137,50.3504961],[-122.950795,50.3711984],[-122.9325221,50.3711521],[-122.9321048,50.399793],[-122.8874234,50.3999748],[-122.8873385,50.4256108],[-122.6620152,50.4256959],[-122.6623083,50.3994506],[-122.5990316,50.3992413],[-122.5988274,50.3755206],[-122.5724832,50.3753706],[-122.5735621,50.2493891],[-122.5990415,50.2494643],[-122.5991504,50.2265663],[-122.6185016,50.2266359],[-122.6185741,50.2244081],[-122.6490609,50.2245126],[-122.6492181,50.1993528],[-122.7308575,50.1993758],[-122.7311583,50.1244287],[-122.7490352,50.1245109],[-122.7490541,50.0903032],[-122.7687806,50.0903435],[-122.7689801,49.9494546],[-122.999047,49.9494706],[-122.9991199,49.8754553],[-122.9775894,49.8754553],[-122.9778145,49.6995098],[-122.9992362,49.6994781],[-122.9992524,49.6516526],[-123.0221525,49.6516526],[-123.0221162,49.5995096],[-123.0491898,49.5994625],[-123.0491898,49.5940523],[-123.0664647,49.5940405],[-123.0663594,49.5451868],[-123.0699906,49.5451202],[-123.0699008,49.5413153],[-123.0706835,49.5392837],[-123.0708888,49.5379931],[-123.0711454,49.5368773],[-123.0711069,49.5358115],[-123.0713764,49.532822],[-123.0716458,49.5321141],[-123.07171,49.5313896],[-123.0720308,49.5304153],[-123.0739554,49.5303486],[-123.0748023,49.5294992],[-123.0748151,49.5288079],[-123.0743403,49.5280584],[-123.073532,49.5274588],[-123.0733652,49.5270423],[-123.0732882,49.5255932],[-123.0737116,49.5249602],[-123.0736218,49.5244938],[-123.0992583,49.5244854],[-123.0991649,49.4754502],[-123.071052,49.4755252],[-123.071088,49.4663034],[-123.0739204,49.4663054],[-123.07422,49.4505028],[-123.0746319,49.4500858],[-123.074651,49.449329],[-123.0745999,49.449018],[-123.0744619,49.4486927],[-123.0743336,49.4479899],[-123.0742427,49.4477688],[-123.0743061,49.4447473],[-123.0747103,49.4447556],[-123.0746384,49.4377306],[-122.9996506,49.4377363],[-122.9996506,49.4369214],[-122.8606163,49.4415314],[-122.8102616,49.4423972],[-122.8098984,49.3766739],[-122.4036093,49.3766617],[-122.4036341,49.3771944],[-122.264739,49.3773028],[-122.263542,49.2360088],[-122.2155742,49.236139],[-122.0580956,49.235878],[-121.9538274,49.2966525],[-121.9400911,49.3045389],[-121.9235761,49.3142257],[-121.8990871,49.3225436],[-121.8883447,49.3259752],[-121.8552982,49.3363575],[-121.832697,49.3441519],[-121.7671336,49.3654361],[-121.6736683,49.3654589],[-121.6404153,49.3743775],[-121.5961976,49.3860493],[-121.5861178,49.3879193],[-121.5213684,49.3994649],[-121.5117375,49.4038378],[-121.4679302,49.4229024],[-121.4416803,49.4345607],[-121.422429,49.4345788],[-121.3462885,49.3932312],[-121.3480144,49.3412388],[-121.5135035,49.320577],[-121.6031683,49.2771727],[-121.6584065,49.1856125],[-121.679953,49.1654109],[-121.7815793,49.0702559],[-121.8076228,49.0622471],[-121.9393997,49.0636219],[-121.9725524,49.0424179],[-121.9921394,49.0332869],[-122.0035289,49.0273413],[-122.0178564,49.0241067],[-122.1108634,48.9992786],[-122.1493067,48.9995305],[-122.1492705,48.9991498],[-122.1991447,48.9996019],[-122.199181,48.9991974],[-122.234365,48.9994829],[-122.234365,49.000173],[-122.3994722,49.0012385],[-122.4521338,49.0016326],[-122.4521338,49.000883],[-122.4584089,49.0009306],[-122.4584814,48.9993124],[-122.4992458,48.9995022],[-122.4992458,48.9992906],[-122.5492618,48.9995107],[-122.5492564,48.9993206],[-122.6580785,48.9994212],[-122.6581061,48.9954007],[-122.7067604,48.9955344],[-122.7519761,48.9956392],[-122.7922063,48.9957204],[-122.7921907,48.9994331],[-123.0350417,48.9995724],[-123.0350437,49.0000958],[-123.0397091,49.0000536],[-123.0397444,49.0001812],[-123.0485506,49.0001348],[-123.0485329,49.0004712],[-123.0557122,49.000448],[-123.0556324,49.0002284],[-123.0641365,49.0001293],[-123.064158,48.9999421],[-123.074899,48.9996928],[-123.0750717,49.0006218],[-123.0899573,49.0003726],[-123.109229,48.9999421],[-123.1271193,49.0003046],[-123.1359953,48.9998741],[-123.1362716,49.0005765],[-123.153851,48.9998061],[-123.1540533,49.0006806],[-123.1710015,49.0001274],[-123.2000916,48.9996849],[-123.2003446,49.0497785],[-123.2108845,49.0497232],[-123.2112218,49.051989],[-123.2070479,49.0520857],[-123.2078911,49.0607884],[-123.2191688,49.0600978],[-123.218958,49.0612719],[-123.2251766,49.0612719],[-123.2253874,49.0622388],[-123.2297088,49.0620316],[-123.2298142,49.068592],[-123.2331869,49.0687301],[-123.2335031,49.0705945],[-123.249313,49.0702493],[-123.2497346,49.0802606],[-123.2751358,49.0803986],[-123.2751358,49.0870947],[-123.299483,49.0873018],[-123.29944,49.080253],[-123.3254508,49.0803944],[-123.3254353,49.1154662],[-123.2750966,49.1503341],[-123.275181,49.1873267],[-123.2788067,49.1871063],[-123.278891,49.1910741],[-123.3004767,49.1910741],[-123.3004186,49.2622933],[-123.3126185,49.2622416],[-123.3125958,49.2714948],[-123.3154251,49.2714727],[-123.3156628,49.2818906],[-123.3174735,49.2818832],[-123.3174961,49.2918488],[-123.3190353,49.2918488],[-123.3190692,49.298602],[-123.3202349,49.2985651],[-123.3202786,49.3019749],[-123.3222679,49.3019605],[-123.3223943,49.3118263],[-123.3254002,49.3118086],[-123.3253898,49.3201721],[-123.3192695,49.3201957],[-123.3192242,49.3246748],[-123.3179437,49.3246596],[-123.3179861,49.3254065],[-123.3176032,49.3272567]]],"terms_url":"http://imagery.paulnorman.ca/tiles/about.html","terms_text":"Copyright Province of British Columbia, City of Surrey"},{"id":"osm-cambodia_laos_thailand_vietnam-bilingual","name":"Cambodia, Laos, Thailand, Vietnam, Myanmar bilingual","type":"tms","template":"http://{switch:a,b,c,d}.tile.osm-tools.org/osm_then/{zoom}/{x}/{y}.png","scaleExtent":[0,19],"polygon":[[[92.1023798,20.8135629],[93.5690546,24.0975527],[94.1733026,23.9269484],[95.1950312,26.707274],[96.7550898,27.5286657],[97.5845575,28.5805966],[98.738122,27.514051],[98.7436151,25.8799151],[97.6779413,24.7577376],[97.9635858,24.042382],[98.8205194,24.1627239],[99.5236444,22.9593356],[100.3695917,21.5051376],[101.7923212,22.4830518],[105.3628778,23.3331079],[106.8185663,22.8480137],[108.1973505,21.3619661],[107.4389505,18.8539792],[117.1453714,7.4656173],[119.6172953,5.2875389],[118.1231546,4.0502277],[117.2552347,4.3624942],[115.8654642,4.3460623],[115.5084085,3.0249771],[114.552598,1.5100953],[113.5418558,1.2574836],[112.9650736,1.5704982],[112.2454691,1.5100953],[111.67418,1.0158321],[110.4546976,0.9004918],[109.4988871,1.9218969],[103.2256937,1.1256762],[100.4626322,3.2388904],[97.6721048,8.0588831],[93.892808,15.9398659],[92.1023798,20.8135629]]],"terms_url":"http://www.osm-tools.org/","terms_text":"© osm-tools.org & OpenStreetMap contributors, CC-BY-SA"},{"id":"South_Africa-CapeTown-Aerial-2013","name":"City of Cape Town 2013 Aerial","type":"tms","template":"http://{switch:a,b,c}.coct.aerial.openstreetmap.org.za/layer/za_coct_aerial_2013/{zoom}/{x}/{y}.jpg","description":"OpenStreetMap use only. City of Cape Town Aerial ortho-photography of the municipal area. 12cm ground sample distance","scaleExtent":[1,21],"polygon":[[[18.4486565,-33.893623],[18.4485868,-33.902644],[18.4702,-33.9027665],[18.4813902,-33.8472383],[18.4492466,-33.801069],[18.4281537,-33.7356408],[18.43914,-33.7177232],[18.4071895,-33.6589917],[18.3322379,-33.5775191],[18.3324525,-33.5504487],[18.353996,-33.5505918],[18.3542535,-33.5236025],[18.3652398,-33.5236561],[18.3650252,-33.5148009],[18.3760115,-33.5147652],[18.3760545,-33.5058017],[18.4296557,-33.5059449],[18.4296986,-33.4878541],[18.4404919,-33.4878899],[18.4405991,-33.4698849],[18.4943721,-33.4700997],[18.4943292,-33.4791564],[18.5158297,-33.4791743],[18.5157439,-33.4881941],[18.5264727,-33.4883015],[18.5263225,-33.5243538],[18.5479304,-33.5244253],[18.5479519,-33.5153913],[18.5693666,-33.5154987],[18.5693666,-33.524479],[18.5801169,-33.5245327],[18.580074,-33.5425978],[18.5907814,-33.5425978],[18.5907385,-33.5606413],[18.5799453,-33.5605341],[18.5798809,-33.569617],[18.5906956,-33.569617],[18.5906526,-33.5786811],[18.6230108,-33.5787347],[18.622925,-33.5877264],[18.6659691,-33.5878872],[18.6659262,-33.614928],[18.6767194,-33.6149726],[18.6765772,-33.6510279],[18.687298,-33.6510167],[18.6873409,-33.6600365],[18.6980697,-33.6600901],[18.6980697,-33.6690733],[18.7520358,-33.6692519],[18.7520787,-33.6421924],[18.7736437,-33.642246],[18.773708,-33.6331886],[18.8274595,-33.6332958],[18.8275239,-33.6603044],[18.8166663,-33.6602866],[18.8166019,-33.6783233],[18.8058087,-33.6783055],[18.8058087,-33.7053892],[18.8273951,-33.7054428],[18.8273308,-33.7234701],[18.838124,-33.7234344],[18.8380381,-33.7413865],[18.8165161,-33.7413687],[18.8163659,-33.7955057],[18.8055941,-33.7955057],[18.8055083,-33.8135675],[18.794758,-33.8135497],[18.7947151,-33.8315364],[18.7731072,-33.8315186],[18.7731287,-33.8405194],[18.7623569,-33.8405194],[18.7622711,-33.903588],[18.7514564,-33.9035167],[18.7510809,-33.9847823],[18.7619063,-33.9848001],[18.7617776,-34.0298785],[18.772603,-34.0298963],[18.7725815,-34.0389073],[18.7940338,-34.0389406],[18.7938756,-34.0406987],[18.7984461,-34.0411855],[18.8032445,-34.0411788],[18.8034055,-34.0389206],[18.8159367,-34.038974],[18.8163444,-34.0299318],[18.8379845,-34.0316479],[18.8380006,-34.030003],[18.8484183,-34.0300074],[18.8484666,-34.0218491],[18.859925,-34.0234675],[18.8598606,-34.0210132],[18.868272,-34.0220803],[18.8681862,-34.0211733],[18.8854596,-34.0234319],[18.8851806,-34.0213156],[18.9025184,-34.021031],[18.9025828,-34.0119958],[18.9134189,-34.0119958],[18.9134833,-33.9939582],[18.9458844,-33.9940294],[18.9458629,-34.003102],[18.9674279,-34.0029953],[18.9674708,-34.0120848],[18.9782211,-34.0120848],[18.9783284,-34.0211377],[18.9891431,-34.0211377],[18.9891645,-34.039134],[19.0000167,-34.0391251],[19.0000221,-34.0571798],[19.0108368,-34.0572509],[19.0107939,-34.0841436],[19.0000007,-34.0841258],[19.0000221,-34.0931977],[18.9891538,-34.0931711],[18.9891753,-34.1021976],[18.9783177,-34.1021798],[18.9783177,-34.111232],[18.967503,-34.1112143],[18.9674923,-34.1292536],[18.9566025,-34.1292358],[18.9565596,-34.1382408],[18.9674172,-34.1383118],[18.9674172,-34.1473157],[18.9891753,-34.147298],[18.9891753,-34.165303],[18.9782748,-34.1652852],[18.9783177,-34.1742863],[18.9674172,-34.1742685],[18.9674601,-34.1833042],[18.9565596,-34.1833219],[18.9565596,-34.1923565],[18.9457449,-34.192321],[18.945702,-34.2013192],[18.9348659,-34.2013725],[18.9348873,-34.2193305],[18.9023575,-34.2193482],[18.9017567,-34.2362557],[18.8878414,-34.2373467],[18.8894185,-34.2554123],[18.8805887,-34.2553414],[18.8792744,-34.2644348],[18.8696882,-34.2644126],[18.8697097,-34.2734386],[18.8371369,-34.2734208],[18.8371155,-34.2643771],[18.848016,-34.2644037],[18.8480267,-34.237391],[18.8154861,-34.210281],[18.8156471,-34.1741265],[18.8548824,-34.1562743],[18.7617561,-34.0840547],[18.6533734,-34.077479],[18.4797433,-34.1101217],[18.4463713,-34.1342269],[18.4444508,-34.1640868],[18.4359965,-34.1640513],[18.435975,-34.1820172],[18.4468111,-34.182106],[18.4467253,-34.1911052],[18.4659299,-34.1912117],[18.4866151,-34.2453911],[18.4788904,-34.2543659],[18.4860036,-34.2543748],[18.4677109,-34.2994116],[18.4892222,-34.3445792],[18.500112,-34.3445837],[18.4999189,-34.3626174],[18.467432,-34.3625111],[18.4673676,-34.3534947],[18.3916005,-34.3170651],[18.3917722,-34.2900161],[18.3701643,-34.2808678],[18.370682,-34.2178866],[18.3492324,-34.1816178],[18.3274743,-34.1814936],[18.3276674,-34.1634565],[18.3118746,-34.1543832],[18.3114025,-34.1435331],[18.3236656,-34.1346886],[18.3499297,-34.1042053],[18.3393189,-34.0882843],[18.3612487,-34.0597219],[18.3550474,-34.0553843],[18.3427522,-34.064326],[18.3199963,-34.0644326],[18.296071,-34.045126],[18.3068213,-34.0252637],[18.3287725,-34.0191992],[18.3289227,-34.001252],[18.3397374,-34.0012698],[18.3398017,-33.9866282],[18.3628687,-33.9735145],[18.3638129,-33.9292474],[18.3726212,-33.9292741],[18.3728358,-33.917763],[18.3977267,-33.8933469],[18.4486565,-33.893623]]],"terms_url":"https://www.capetown.gov.za","terms_text":"City of Cape Town Aerial - OPENSTREETMAP USE ONLY"},{"id":"South_Africa-CapeTown-Aerial","name":"City of Cape Town 2015 Aerial","type":"tms","template":"http://{switch:a,b,c}.coct.aerial.openstreetmap.org.za/layer/za_coct_aerial_2015/{zoom}/{x}/{y}.jpg","description":"OpenStreetMap use only. City of Cape Town Aerial ortho-photography of the municipal area. 8cm ground sample distance","scaleExtent":[1,21],"polygon":[[[18.4486565,-33.893623],[18.4485868,-33.902644],[18.4702,-33.9027665],[18.4813902,-33.8472383],[18.4492466,-33.801069],[18.4281537,-33.7356408],[18.43914,-33.7177232],[18.4071895,-33.6589917],[18.3322379,-33.5775191],[18.3324525,-33.5504487],[18.353996,-33.5505918],[18.3542535,-33.5236025],[18.3652398,-33.5236561],[18.3650252,-33.5148009],[18.3760115,-33.5147652],[18.3760545,-33.5058017],[18.4296557,-33.5059449],[18.4296986,-33.4878541],[18.4404919,-33.4878899],[18.4405991,-33.4698849],[18.4943721,-33.4700997],[18.4943292,-33.4791564],[18.5158297,-33.4791743],[18.5157439,-33.4881941],[18.5264727,-33.4883015],[18.5263225,-33.5243538],[18.5479304,-33.5244253],[18.5479519,-33.5153913],[18.5693666,-33.5154987],[18.5693666,-33.524479],[18.5801169,-33.5245327],[18.580074,-33.5425978],[18.5907814,-33.5425978],[18.5907385,-33.5606413],[18.5799453,-33.5605341],[18.5798809,-33.569617],[18.5906956,-33.569617],[18.5906526,-33.5786811],[18.6230108,-33.5787347],[18.622925,-33.5877264],[18.6659691,-33.5878872],[18.6659262,-33.614928],[18.6767194,-33.6149726],[18.6765772,-33.6510279],[18.687298,-33.6510167],[18.6873409,-33.6600365],[18.6980697,-33.6600901],[18.6980697,-33.6690733],[18.7520358,-33.6692519],[18.7520787,-33.6421924],[18.7736437,-33.642246],[18.773708,-33.6331886],[18.8274595,-33.6332958],[18.8275239,-33.6603044],[18.8166663,-33.6602866],[18.8166019,-33.6783233],[18.8058087,-33.6783055],[18.8058087,-33.7053892],[18.8273951,-33.7054428],[18.8273308,-33.7234701],[18.838124,-33.7234344],[18.8380381,-33.7413865],[18.8165161,-33.7413687],[18.8163659,-33.7955057],[18.8055941,-33.7955057],[18.8055083,-33.8135675],[18.794758,-33.8135497],[18.7947151,-33.8315364],[18.7731072,-33.8315186],[18.7731287,-33.8405194],[18.7623569,-33.8405194],[18.7622711,-33.903588],[18.7514564,-33.9035167],[18.7510809,-33.9847823],[18.7619063,-33.9848001],[18.7617776,-34.0298785],[18.772603,-34.0298963],[18.7725815,-34.0389073],[18.7940338,-34.0389406],[18.7938756,-34.0406987],[18.7984461,-34.0411855],[18.8032445,-34.0411788],[18.8034055,-34.0389206],[18.8159367,-34.038974],[18.8163444,-34.0299318],[18.8379845,-34.0316479],[18.8380006,-34.030003],[18.8484183,-34.0300074],[18.8484666,-34.0218491],[18.859925,-34.0234675],[18.8598606,-34.0210132],[18.868272,-34.0220803],[18.8681862,-34.0211733],[18.8854596,-34.0234319],[18.8851806,-34.0213156],[18.9025184,-34.021031],[18.9025828,-34.0119958],[18.9134189,-34.0119958],[18.9134833,-33.9939582],[18.9458844,-33.9940294],[18.9458629,-34.003102],[18.9674279,-34.0029953],[18.9674708,-34.0120848],[18.9782211,-34.0120848],[18.9783284,-34.0211377],[18.9891431,-34.0211377],[18.9891645,-34.039134],[19.0000167,-34.0391251],[19.0000221,-34.0571798],[19.0108368,-34.0572509],[19.0107939,-34.0841436],[19.0000007,-34.0841258],[19.0000221,-34.0931977],[18.9891538,-34.0931711],[18.9891753,-34.1021976],[18.9783177,-34.1021798],[18.9783177,-34.111232],[18.967503,-34.1112143],[18.9674923,-34.1292536],[18.9566025,-34.1292358],[18.9565596,-34.1382408],[18.9674172,-34.1383118],[18.9674172,-34.1473157],[18.9891753,-34.147298],[18.9891753,-34.165303],[18.9782748,-34.1652852],[18.9783177,-34.1742863],[18.9674172,-34.1742685],[18.9674601,-34.1833042],[18.9565596,-34.1833219],[18.9565596,-34.1923565],[18.9457449,-34.192321],[18.945702,-34.2013192],[18.9348659,-34.2013725],[18.9348873,-34.2193305],[18.9023575,-34.2193482],[18.9017567,-34.2362557],[18.8878414,-34.2373467],[18.8894185,-34.2554123],[18.8805887,-34.2553414],[18.8792744,-34.2644348],[18.8696882,-34.2644126],[18.8697097,-34.2734386],[18.8371369,-34.2734208],[18.8371155,-34.2643771],[18.848016,-34.2644037],[18.8480267,-34.237391],[18.8154861,-34.210281],[18.8156471,-34.1741265],[18.8548824,-34.1562743],[18.7617561,-34.0840547],[18.6533734,-34.077479],[18.4797433,-34.1101217],[18.4463713,-34.1342269],[18.4444508,-34.1640868],[18.4359965,-34.1640513],[18.435975,-34.1820172],[18.4468111,-34.182106],[18.4467253,-34.1911052],[18.4659299,-34.1912117],[18.4866151,-34.2453911],[18.4788904,-34.2543659],[18.4860036,-34.2543748],[18.4677109,-34.2994116],[18.4892222,-34.3445792],[18.500112,-34.3445837],[18.4999189,-34.3626174],[18.467432,-34.3625111],[18.4673676,-34.3534947],[18.3916005,-34.3170651],[18.3917722,-34.2900161],[18.3701643,-34.2808678],[18.370682,-34.2178866],[18.3492324,-34.1816178],[18.3274743,-34.1814936],[18.3276674,-34.1634565],[18.3118746,-34.1543832],[18.3114025,-34.1435331],[18.3236656,-34.1346886],[18.3499297,-34.1042053],[18.3393189,-34.0882843],[18.3612487,-34.0597219],[18.3550474,-34.0553843],[18.3427522,-34.064326],[18.3199963,-34.0644326],[18.296071,-34.045126],[18.3068213,-34.0252637],[18.3287725,-34.0191992],[18.3289227,-34.001252],[18.3397374,-34.0012698],[18.3398017,-33.9866282],[18.3628687,-33.9735145],[18.3638129,-33.9292474],[18.3726212,-33.9292741],[18.3728358,-33.917763],[18.3977267,-33.8933469],[18.4486565,-33.893623]]],"terms_url":"https://www.capetown.gov.za","terms_text":"City of Cape Town Aerial - OPENSTREETMAP USE ONLY","best":true},{"id":"Czech_CUZK-KM-tms","name":"Czech CUZK:KM tiles proxy","type":"tms","template":"http://osm-{switch:a,b,c}.zby.cz/tiles_cuzk.php/{zoom}/{x}/{y}.png","scaleExtent":[13,18],"polygon":[[[15.0063684,49.0177392],[15.1559854,49.0013828],[15.190896,48.9424551],[15.3105895,48.9882938],[15.4053469,48.9752013],[15.5400022,48.9162426],[15.7145553,48.8670572],[15.8342488,48.880178],[15.968904,48.8178233],[16.0885976,48.7455261],[16.3978059,48.7455261],[16.4875761,48.8145394],[16.6721036,48.7784014],[16.6820781,48.7356594],[16.9015163,48.7126294],[16.9464014,48.6237005],[17.1159672,48.8375227],[17.2107246,48.880178],[17.4052266,48.8178233],[17.4800351,48.8539329],[17.5299074,48.8178233],[17.7044605,48.8670572],[17.8141796,48.9359033],[17.8840008,48.9359033],[17.9438476,49.0210099],[18.0635412,49.0340903],[18.1184007,49.0994409],[18.1981964,49.3047337],[18.3877112,49.3339917],[18.577226,49.5091747],[18.7567663,49.4994587],[18.8465365,49.5253637],[18.8764598,49.5706645],[18.7966641,49.693412],[18.64206,49.7095399],[18.5872004,49.8351543],[18.6121366,49.8833809],[18.5622643,49.9347695],[18.512392,49.9058702],[18.362775,49.9540261],[18.3278644,49.9219275],[18.2630304,49.9732751],[18.1184007,50.0053395],[18.0635412,50.075806],[17.9139242,49.9796897],[17.779269,50.0309757],[17.714435,50.1237921],[17.6047159,50.1653411],[17.7593201,50.21962],[17.7343839,50.3439092],[17.6396265,50.2802117],[17.3802905,50.2802117],[17.3503671,50.3439092],[17.2805459,50.3375433],[17.1857885,50.4075214],[16.9015163,50.4615247],[16.8666057,50.4138779],[16.9663503,50.3184404],[17.0361715,50.2323826],[16.8366823,50.21962],[16.7120015,50.1046034],[16.5823335,50.1589513],[16.5623846,50.2387626],[16.4327166,50.3375433],[16.3529209,50.3916263],[16.2781124,50.3916263],[16.2082911,50.4456477],[16.3978059,50.5344899],[16.4476782,50.5978464],[16.3529209,50.670601],[16.2382145,50.6769221],[16.2182656,50.6326561],[16.1284954,50.6832425],[16.0486997,50.6073425],[15.988853,50.7021983],[15.8741467,50.6832425],[15.8292616,50.7653291],[15.729517,50.743243],[15.450232,50.8157725],[15.3903852,50.7747914],[15.3804108,50.8598659],[15.2956278,50.8850434],[15.2956278,50.9887568],[15.1709471,51.0201394],[14.9914067,51.0013124],[15.0063684,50.8881896],[14.8417898,50.8756034],[14.7969047,50.8252246],[14.6323261,50.8567177],[14.6622495,50.9353576],[14.5724793,50.9227841],[14.6123772,50.9856174],[14.4976708,51.0483657],[14.4178751,51.0232765],[14.3081561,51.0671736],[14.2532965,51.0044508],[14.4029134,50.9322145],[14.3729901,50.897627],[14.2433221,50.9070625],[14.2084114,50.844123],[14.0338583,50.8126214],[13.9789988,50.8252246],[13.9041903,50.7968626],[13.8742669,50.740087],[13.5351352,50.7243038],[13.530148,50.6579561],[13.4703012,50.6136722],[13.3905055,50.664279],[13.3256715,50.5883483],[13.250863,50.6105074],[13.1960035,50.5059517],[13.0513738,50.5218084],[12.9665909,50.4106997],[12.8269484,50.4710483],[12.7022676,50.4138779],[12.5077656,50.401164],[12.343187,50.2547088],[12.323238,50.1845054],[12.2484296,50.2738373],[12.1736211,50.3311765],[12.0988126,50.33436],[12.1187616,50.25152],[12.2234934,50.1653411],[12.2035445,50.1237921],[12.5027784,49.9732751],[12.4778422,49.9379795],[12.5476634,49.9155052],[12.4678677,49.8029766],[12.408021,49.7611134],[12.4828294,49.6869593],[12.5327017,49.6869593],[12.5177401,49.6288466],[12.6075102,49.5415474],[12.6723442,49.4378793],[12.8119867,49.3469896],[12.9466419,49.3437405],[13.2309141,49.1288206],[13.3256715,49.1059712],[13.4353906,49.0438984],[13.4154417,48.9948387],[13.5002246,48.949006],[13.5650586,48.9882938],[13.6847522,48.8834577],[13.7445989,48.9031312],[13.8243946,48.7751149],[13.8992031,48.7751149],[14.0587945,48.676418],[14.0438328,48.6302932],[14.1435774,48.5907241],[14.3729901,48.5610269],[14.4827091,48.6500662],[14.5774665,48.607215],[14.6273389,48.6335892],[14.7071346,48.5808269],[14.7470324,48.7027561],[14.8118664,48.7389485],[14.8168536,48.794831],[14.9864195,48.7652539],[15.0063684,49.0177392]]],"overlay":true},{"id":"Czech_RUIAN-budovy","name":"Czech RUIAN budovy","type":"tms","template":"http://tile.poloha.net/budovy/{zoom}/{x}/{y}.png","scaleExtent":[12,20],"polygon":[[[15.0063684,49.0177392],[15.1559854,49.0013828],[15.190896,48.9424551],[15.3105895,48.9882938],[15.4053469,48.9752013],[15.5400022,48.9162426],[15.7145553,48.8670572],[15.8342488,48.880178],[15.968904,48.8178233],[16.0885976,48.7455261],[16.3978059,48.7455261],[16.4875761,48.8145394],[16.6721036,48.7784014],[16.6820781,48.7356594],[16.9015163,48.7126294],[16.9464014,48.6237005],[17.1159672,48.8375227],[17.2107246,48.880178],[17.4052266,48.8178233],[17.4800351,48.8539329],[17.5299074,48.8178233],[17.7044605,48.8670572],[17.8141796,48.9359033],[17.8840008,48.9359033],[17.9438476,49.0210099],[18.0635412,49.0340903],[18.1184007,49.0994409],[18.1981964,49.3047337],[18.3877112,49.3339917],[18.577226,49.5091747],[18.7567663,49.4994587],[18.8465365,49.5253637],[18.8764598,49.5706645],[18.7966641,49.693412],[18.64206,49.7095399],[18.5872004,49.8351543],[18.6121366,49.8833809],[18.5622643,49.9347695],[18.512392,49.9058702],[18.362775,49.9540261],[18.3278644,49.9219275],[18.2630304,49.9732751],[18.1184007,50.0053395],[18.0635412,50.075806],[17.9139242,49.9796897],[17.779269,50.0309757],[17.714435,50.1237921],[17.6047159,50.1653411],[17.7593201,50.21962],[17.7343839,50.3439092],[17.6396265,50.2802117],[17.3802905,50.2802117],[17.3503671,50.3439092],[17.2805459,50.3375433],[17.1857885,50.4075214],[16.9015163,50.4615247],[16.8666057,50.4138779],[16.9663503,50.3184404],[17.0361715,50.2323826],[16.8366823,50.21962],[16.7120015,50.1046034],[16.5823335,50.1589513],[16.5623846,50.2387626],[16.4327166,50.3375433],[16.3529209,50.3916263],[16.2781124,50.3916263],[16.2082911,50.4456477],[16.3978059,50.5344899],[16.4476782,50.5978464],[16.3529209,50.670601],[16.2382145,50.6769221],[16.2182656,50.6326561],[16.1284954,50.6832425],[16.0486997,50.6073425],[15.988853,50.7021983],[15.8741467,50.6832425],[15.8292616,50.7653291],[15.729517,50.743243],[15.450232,50.8157725],[15.3903852,50.7747914],[15.3804108,50.8598659],[15.2956278,50.8850434],[15.2956278,50.9887568],[15.1709471,51.0201394],[14.9914067,51.0013124],[15.0063684,50.8881896],[14.8417898,50.8756034],[14.7969047,50.8252246],[14.6323261,50.8567177],[14.6622495,50.9353576],[14.5724793,50.9227841],[14.6123772,50.9856174],[14.4976708,51.0483657],[14.4178751,51.0232765],[14.3081561,51.0671736],[14.2532965,51.0044508],[14.4029134,50.9322145],[14.3729901,50.897627],[14.2433221,50.9070625],[14.2084114,50.844123],[14.0338583,50.8126214],[13.9789988,50.8252246],[13.9041903,50.7968626],[13.8742669,50.740087],[13.5351352,50.7243038],[13.530148,50.6579561],[13.4703012,50.6136722],[13.3905055,50.664279],[13.3256715,50.5883483],[13.250863,50.6105074],[13.1960035,50.5059517],[13.0513738,50.5218084],[12.9665909,50.4106997],[12.8269484,50.4710483],[12.7022676,50.4138779],[12.5077656,50.401164],[12.343187,50.2547088],[12.323238,50.1845054],[12.2484296,50.2738373],[12.1736211,50.3311765],[12.0988126,50.33436],[12.1187616,50.25152],[12.2234934,50.1653411],[12.2035445,50.1237921],[12.5027784,49.9732751],[12.4778422,49.9379795],[12.5476634,49.9155052],[12.4678677,49.8029766],[12.408021,49.7611134],[12.4828294,49.6869593],[12.5327017,49.6869593],[12.5177401,49.6288466],[12.6075102,49.5415474],[12.6723442,49.4378793],[12.8119867,49.3469896],[12.9466419,49.3437405],[13.2309141,49.1288206],[13.3256715,49.1059712],[13.4353906,49.0438984],[13.4154417,48.9948387],[13.5002246,48.949006],[13.5650586,48.9882938],[13.6847522,48.8834577],[13.7445989,48.9031312],[13.8243946,48.7751149],[13.8992031,48.7751149],[14.0587945,48.676418],[14.0438328,48.6302932],[14.1435774,48.5907241],[14.3729901,48.5610269],[14.4827091,48.6500662],[14.5774665,48.607215],[14.6273389,48.6335892],[14.7071346,48.5808269],[14.7470324,48.7027561],[14.8118664,48.7389485],[14.8168536,48.794831],[14.9864195,48.7652539]]],"terms_url":"http://poloha.net/"},{"id":"Czech_RUIAN-parcely","name":"Czech RUIAN parcely","type":"tms","template":"http://tile.poloha.net/parcely/{zoom}/{x}/{y}.png","scaleExtent":[12,20],"polygon":[[[15.0063684,49.0177392],[15.1559854,49.0013828],[15.190896,48.9424551],[15.3105895,48.9882938],[15.4053469,48.9752013],[15.5400022,48.9162426],[15.7145553,48.8670572],[15.8342488,48.880178],[15.968904,48.8178233],[16.0885976,48.7455261],[16.3978059,48.7455261],[16.4875761,48.8145394],[16.6721036,48.7784014],[16.6820781,48.7356594],[16.9015163,48.7126294],[16.9464014,48.6237005],[17.1159672,48.8375227],[17.2107246,48.880178],[17.4052266,48.8178233],[17.4800351,48.8539329],[17.5299074,48.8178233],[17.7044605,48.8670572],[17.8141796,48.9359033],[17.8840008,48.9359033],[17.9438476,49.0210099],[18.0635412,49.0340903],[18.1184007,49.0994409],[18.1981964,49.3047337],[18.3877112,49.3339917],[18.577226,49.5091747],[18.7567663,49.4994587],[18.8465365,49.5253637],[18.8764598,49.5706645],[18.7966641,49.693412],[18.64206,49.7095399],[18.5872004,49.8351543],[18.6121366,49.8833809],[18.5622643,49.9347695],[18.512392,49.9058702],[18.362775,49.9540261],[18.3278644,49.9219275],[18.2630304,49.9732751],[18.1184007,50.0053395],[18.0635412,50.075806],[17.9139242,49.9796897],[17.779269,50.0309757],[17.714435,50.1237921],[17.6047159,50.1653411],[17.7593201,50.21962],[17.7343839,50.3439092],[17.6396265,50.2802117],[17.3802905,50.2802117],[17.3503671,50.3439092],[17.2805459,50.3375433],[17.1857885,50.4075214],[16.9015163,50.4615247],[16.8666057,50.4138779],[16.9663503,50.3184404],[17.0361715,50.2323826],[16.8366823,50.21962],[16.7120015,50.1046034],[16.5823335,50.1589513],[16.5623846,50.2387626],[16.4327166,50.3375433],[16.3529209,50.3916263],[16.2781124,50.3916263],[16.2082911,50.4456477],[16.3978059,50.5344899],[16.4476782,50.5978464],[16.3529209,50.670601],[16.2382145,50.6769221],[16.2182656,50.6326561],[16.1284954,50.6832425],[16.0486997,50.6073425],[15.988853,50.7021983],[15.8741467,50.6832425],[15.8292616,50.7653291],[15.729517,50.743243],[15.450232,50.8157725],[15.3903852,50.7747914],[15.3804108,50.8598659],[15.2956278,50.8850434],[15.2956278,50.9887568],[15.1709471,51.0201394],[14.9914067,51.0013124],[15.0063684,50.8881896],[14.8417898,50.8756034],[14.7969047,50.8252246],[14.6323261,50.8567177],[14.6622495,50.9353576],[14.5724793,50.9227841],[14.6123772,50.9856174],[14.4976708,51.0483657],[14.4178751,51.0232765],[14.3081561,51.0671736],[14.2532965,51.0044508],[14.4029134,50.9322145],[14.3729901,50.897627],[14.2433221,50.9070625],[14.2084114,50.844123],[14.0338583,50.8126214],[13.9789988,50.8252246],[13.9041903,50.7968626],[13.8742669,50.740087],[13.5351352,50.7243038],[13.530148,50.6579561],[13.4703012,50.6136722],[13.3905055,50.664279],[13.3256715,50.5883483],[13.250863,50.6105074],[13.1960035,50.5059517],[13.0513738,50.5218084],[12.9665909,50.4106997],[12.8269484,50.4710483],[12.7022676,50.4138779],[12.5077656,50.401164],[12.343187,50.2547088],[12.323238,50.1845054],[12.2484296,50.2738373],[12.1736211,50.3311765],[12.0988126,50.33436],[12.1187616,50.25152],[12.2234934,50.1653411],[12.2035445,50.1237921],[12.5027784,49.9732751],[12.4778422,49.9379795],[12.5476634,49.9155052],[12.4678677,49.8029766],[12.408021,49.7611134],[12.4828294,49.6869593],[12.5327017,49.6869593],[12.5177401,49.6288466],[12.6075102,49.5415474],[12.6723442,49.4378793],[12.8119867,49.3469896],[12.9466419,49.3437405],[13.2309141,49.1288206],[13.3256715,49.1059712],[13.4353906,49.0438984],[13.4154417,48.9948387],[13.5002246,48.949006],[13.5650586,48.9882938],[13.6847522,48.8834577],[13.7445989,48.9031312],[13.8243946,48.7751149],[13.8992031,48.7751149],[14.0587945,48.676418],[14.0438328,48.6302932],[14.1435774,48.5907241],[14.3729901,48.5610269],[14.4827091,48.6500662],[14.5774665,48.607215],[14.6273389,48.6335892],[14.7071346,48.5808269],[14.7470324,48.7027561],[14.8118664,48.7389485],[14.8168536,48.794831],[14.9864195,48.7652539]]],"terms_url":"http://poloha.net/"},{"id":"Duna_2013","name":"Danube flood ortophoto 2013","type":"tms","template":"http://e.tile.openstreetmap.hu/dunai-arviz-2013/{zoom}/{x}/{y}.jpg","scaleExtent":[10,20],"polygon":[[[19.0773152,47.6959718],[19.0779881,47.6959835],[19.0946205,47.6944562],[19.0805603,47.595874],[19.0743376,47.5890907],[19.0795196,47.5888284],[19.07717,47.5724109],[19.0577884,47.5720924],[19.0773152,47.6959718]]],"terms_url":"http://fototerkep.hu/","terms_text":"Fotótérkép.hu"},{"id":"Delaware2012Orthophotography","name":"Delaware 2012 Orthophotography","type":"tms","template":"http://whoots.mapwarper.net/tms/{zoom}/{x}/{y}/0/https://firstmap.delaware.gov/arcgis/services/DE_Imagery/DE_Imagery_2012/ImageServer/WMSServer","description":"This data set consists of 0.3-meter pixel resolution (approximately 1-foot), 4-band true color and near infrared (R, G, B, IR) orthoimages covering New Castle, Kent and Sussex Counties in Delaware.","polygon":[[[-75.01770587603,38.45188674427],[-75.74173524589,38.4499581145],[-75.80699639658,39.73907123636],[-75.75558784863,39.80106251053],[-75.64692187603,39.8563815616],[-75.47114773904,39.84645578141],[-75.37725787603,39.81477822231],[-75.48746302671,39.6718115509],[-75.50901151986,39.43446011595],[-75.39326532808,39.27784018498],[-75.30707135548,39.01666513594],[-75.1931721774,38.82218696272],[-75.05341480753,38.80875503297],[-75.01770587603,38.45188674427]]]},{"id":"maaamet.ee-orto","name":"Estonia Ortho (Maaamet)","type":"tms","template":"http://kaart.maakaart.ee/orto/{zoom}/{x}/{y}.jpeg","scaleExtent":[14,20],"polygon":[[[21.6940073,57.5025466],[21.6940073,59.8274564],[28.2110546,59.8274564],[28.2110546,57.5025466],[21.6940073,57.5025466]]],"terms_text":"Maa-Ameti ortofoto "},{"id":"FOMI_2000","name":"FÖMI ortofotó 2000","type":"tms","template":"http://e.tile.openstreetmap.hu/ortofoto2000/{zoom}/{x}/{y}.jpg","description":"Hungary","scaleExtent":[0,17],"polygon":[[[16.1139147,46.8691038],[16.1789749,46.90662],[16.2000429,46.9415079],[16.2217547,46.9355441],[16.2462784,46.9463851],[16.2553226,46.9642125],[16.2764694,46.9626082],[16.290583,47.0139849],[16.3016199,46.9992329],[16.3414618,46.9965225],[16.3505162,47.0106313],[16.3734016,46.9985929],[16.412765,47.00475],[16.4332705,46.9927417],[16.4478119,47.003893],[16.479997,46.9941169],[16.5121988,47.0011695],[16.4635584,47.0322699],[16.4478586,47.0227481],[16.439123,47.029663],[16.445673,47.038872],[16.520323,47.056103],[16.473213,47.0736169],[16.4637199,47.09392],[16.500798,47.110058],[16.500035,47.123295],[16.5295349,47.1287419],[16.5171609,47.1496938],[16.454951,47.1425878],[16.4648728,47.1683349],[16.4555643,47.1875584],[16.4305559,47.1847022],[16.4195013,47.1949147],[16.4189215,47.2107114],[16.4371293,47.2097043],[16.4426335,47.2337117],[16.4313127,47.2527554],[16.4671512,47.2531652],[16.4892319,47.2798885],[16.4646338,47.3338455],[16.4337002,47.3528101],[16.458513,47.3670496],[16.4454619,47.4070195],[16.4831657,47.4093628],[16.4963821,47.3892659],[16.5170941,47.4100218],[16.5749054,47.4054243],[16.5807291,47.4191699],[16.661847,47.455595],[16.6706419,47.47422],[16.6523395,47.500342],[16.6895619,47.510161],[16.7147797,47.540199],[16.663545,47.567733],[16.673199,47.6049544],[16.6595343,47.6061018],[16.652758,47.622852],[16.6314207,47.6283176],[16.5739108,47.619667],[16.5147382,47.6461964],[16.4967504,47.6393149],[16.425464,47.6621679],[16.4437449,47.674205],[16.4480507,47.6964725],[16.4746984,47.6811576],[16.4872245,47.6979767],[16.5521729,47.7225519],[16.5363779,47.736785],[16.5479799,47.751544],[16.6095193,47.7603722],[16.6344148,47.7590843],[16.65729,47.7414879],[16.7209405,47.7353565],[16.7534062,47.6828165],[16.8301587,47.681058],[16.8394284,47.7045139],[16.8668943,47.7211462],[16.876679,47.6876452],[17.0937421,47.7077706],[17.0706562,47.7285366],[17.0516019,47.7938499],[17.0749479,47.8084997],[17.047139,47.8285635],[17.0519452,47.8377691],[17.0105513,47.8581765],[17.0163878,47.8673325],[17.0857537,47.8746239],[17.113171,47.9271605],[17.0917133,47.9342916],[17.1183782,47.9601083],[17.094657,47.9708775],[17.2010289,48.019992],[17.241769,48.0224651],[17.257955,47.998655],[17.334651,47.993125],[17.4029929,47.947849],[17.4539199,47.8852579],[17.5267369,47.865509],[17.5675779,47.8151289],[17.608402,47.8218859],[17.7085789,47.756678],[17.7798739,47.739487],[17.8660959,47.74575],[17.9001292,47.7392633],[17.946867,47.744668],[17.9708709,47.7578392],[18.0044103,47.7463402],[18.0380583,47.7576812],[18.2958774,47.7314616],[18.4540681,47.7651226],[18.4931553,47.7527552],[18.5590761,47.7659963],[18.6460866,47.7590921],[18.7260691,47.7890411],[18.7411784,47.8138245],[18.7920013,47.8230869],[18.8485417,47.8167221],[18.855876,47.826077],[18.828014,47.834291],[18.8135749,47.85555],[18.76353,47.8716049],[18.756858,47.896838],[18.776746,47.955092],[18.7552499,47.9763469],[18.8157429,47.993442],[18.819998,48.039676],[18.833268,48.048239],[18.8749364,48.0470707],[18.886674,48.058682],[18.9089819,48.051139],[18.9439039,48.058865],[18.9816099,48.0536009],[19.0148639,48.078179],[19.0585249,48.0573529],[19.0843619,48.072781],[19.107402,48.065596],[19.1352889,48.074146],[19.2413679,48.0536529],[19.2557819,48.0715559],[19.3031119,48.088711],[19.3865969,48.091914],[19.400018,48.082304],[19.454053,48.101436],[19.467354,48.083933],[19.4944199,48.109906],[19.492377,48.1396639],[19.5128219,48.154663],[19.504518,48.173443],[19.528967,48.190358],[19.526044,48.20313],[19.577502,48.2160149],[19.6308263,48.2500725],[19.6445239,48.2391719],[19.669857,48.239212],[19.691219,48.203894],[19.721125,48.201473],[19.74618,48.2165119],[19.7871629,48.19253],[19.7987329,48.19482],[19.8052829,48.183733],[19.782415,48.165039],[19.794812,48.153529],[19.821331,48.169081],[19.8452819,48.162742],[19.8551729,48.178431],[19.8601309,48.169409],[19.898745,48.1663119],[19.9145359,48.146863],[19.898298,48.1249019],[19.937383,48.131118],[19.9743939,48.1660049],[19.988706,48.1621679],[20.029038,48.1776849],[20.049449,48.1671999],[20.0729859,48.179606],[20.0700369,48.1917019],[20.1340909,48.225182],[20.1331879,48.253982],[20.206162,48.250979],[20.2038299,48.261906],[20.228466,48.262779],[20.2349469,48.279933],[20.286858,48.26164],[20.3257109,48.272794],[20.3374649,48.301667],[20.3656579,48.316606],[20.384077,48.3511809],[20.4098349,48.365857],[20.402532,48.382565],[20.4205349,48.403858],[20.416228,48.418536],[20.507929,48.489363],[20.5065069,48.534415],[20.537471,48.527878],[20.5464939,48.544292],[20.586595,48.535759],[20.6538739,48.561413],[20.836359,48.58284],[20.8378,48.57421],[20.8504359,48.5816329],[20.8453301,48.5665046],[20.8681549,48.551818],[20.922323,48.559453],[20.9346349,48.538341],[20.955882,48.533963],[20.9561979,48.521666],[20.9815849,48.5177669],[21.0151139,48.532313],[21.0663209,48.525894],[21.1174479,48.4910549],[21.1608749,48.521499],[21.179634,48.518232],[21.221061,48.537497],[21.305488,48.5222489],[21.313377,48.550841],[21.326875,48.554129],[21.319384,48.561201],[21.4154499,48.558951],[21.4226649,48.578821],[21.4406099,48.585104],[21.514091,48.551065],[21.5420199,48.508395],[21.6139329,48.509416],[21.6201879,48.469826],[21.663549,48.417961],[21.6645609,48.392164],[21.7017409,48.380695],[21.711871,48.357617],[21.8174139,48.332787],[21.8352029,48.3346409],[21.837213,48.363253],[21.8842979,48.356047],[21.8848429,48.367539],[21.897883,48.36256],[21.8997959,48.3702229],[21.9281859,48.3615969],[21.9268059,48.370899],[21.949198,48.378728],[21.994463,48.377323],[22.0213259,48.392749],[22.0546049,48.377528],[22.0764859,48.387241],[22.086743,48.371564],[22.1359089,48.380519],[22.131056,48.3912329],[22.152768,48.3962409],[22.1561913,48.4093076],[22.2125722,48.4256468],[22.2371405,48.4100396],[22.2654858,48.4098675],[22.2398761,48.3870055],[22.2675722,48.3611612],[22.3178106,48.3545437],[22.3132861,48.3250712],[22.3372944,48.3079113],[22.3384267,48.2792074],[22.3847547,48.2339632],[22.4006407,48.249198],[22.4328384,48.2525166],[22.456386,48.2423109],[22.4899029,48.2534237],[22.4972201,48.2395546],[22.5161491,48.237965],[22.5311088,48.2094282],[22.5711442,48.1961428],[22.5616362,48.1816066],[22.5982449,48.144756],[22.5902763,48.1073414],[22.6754492,48.091997],[22.7347192,48.119848],[22.7576242,48.1200599],[22.7703914,48.1090162],[22.772319,48.1218742],[22.8027688,48.1221112],[22.8025285,48.1070813],[22.8254256,48.1175119],[22.8364365,48.080249],[22.8611284,48.0750312],[22.8677955,48.0524256],[22.8820424,48.0548053],[22.8659692,48.0113165],[22.835562,47.9905988],[22.8407599,47.9813636],[22.8725729,47.9752683],[22.8697274,47.9659593],[22.8915652,47.9672446],[22.897435,47.9540629],[22.8473299,47.9077579],[22.7928135,47.8908586],[22.7586924,47.8941446],[22.77775,47.8422508],[22.7136344,47.8360928],[22.6801938,47.7877527],[22.6111171,47.7717455],[22.5490018,47.7722246],[22.4812121,47.8108886],[22.4513078,47.803389],[22.4313319,47.7398119],[22.3566167,47.7486206],[22.3177714,47.7660887],[22.3176236,47.7433657],[22.2851369,47.7292757],[22.264325,47.7310675],[22.2589955,47.6979057],[22.2306796,47.693196],[22.1796501,47.5916115],[22.1289245,47.5978984],[22.0942787,47.5583628],[22.0782587,47.5621299],[22.0534529,47.5474795],[22.0712176,47.5380742],[22.0617872,47.5288029],[22.0451278,47.5398919],[22.0367222,47.5326653],[22.0071886,47.48362],[22.0327909,47.4508372],[22.0238835,47.3908631],[22.0119849,47.3758016],[21.9627373,47.381053],[21.9382461,47.3725317],[21.8777922,47.2857763],[21.8872845,47.2730473],[21.8534909,47.2397622],[21.8580662,47.1873597],[21.8124804,47.1667511],[21.7924092,47.1059751],[21.7268258,47.0983882],[21.6976037,47.057915],[21.6504151,47.0408303],[21.6888701,47.0019977],[21.6678744,46.9712337],[21.6814917,46.9652089],[21.6381964,46.9330487],[21.5984455,46.9274708],[21.6142857,46.8867275],[21.6016694,46.8668202],[21.520328,46.8373749],[21.5186086,46.8000703],[21.4831761,46.7650246],[21.5263389,46.7393249],[21.529369,46.7209721],[21.4923253,46.6859652],[21.4728438,46.6959075],[21.4299047,46.693937],[21.4309553,46.6781367],[21.4546661,46.660863],[21.4162375,46.6426231],[21.4097959,46.6218052],[21.3657038,46.6379501],[21.3300499,46.6318155],[21.3139733,46.617666],[21.3012351,46.5908672],[21.3207905,46.5828562],[21.2743045,46.5407362],[21.2600254,46.5021583],[21.2744188,46.4767333],[21.2964506,46.4762973],[21.3174343,46.4507288],[21.2895176,46.4154784],[21.2963256,46.4069601],[21.2250116,46.4136899],[21.2064214,46.4033825],[21.1992563,46.3479034],[21.1762269,46.3357664],[21.180497,46.3044494],[21.1155437,46.3018529],[21.1030549,46.2624637],[21.0708792,46.2539014],[21.0660827,46.2429394],[21.0366237,46.2480392],[21.0246723,46.2665329],[20.960817,46.2623039],[20.9465849,46.2793024],[20.9250701,46.2766191],[20.9218133,46.2618129],[20.8732713,46.2877555],[20.7756538,46.2759602],[20.7490474,46.2508489],[20.7618619,46.204563],[20.727401,46.2077485],[20.7341052,46.1939355],[20.7140487,46.1660531],[20.6843592,46.1447802],[20.6549178,46.1497739],[20.6394471,46.1267602],[20.5450486,46.1790935],[20.5014839,46.190334],[20.4949436,46.1709908],[20.4592293,46.1428837],[20.3975133,46.1574709],[20.3685325,46.1528554],[20.3557074,46.1696256],[20.2968136,46.1521542],[20.2549024,46.1158522],[20.2484757,46.1300956],[20.2330132,46.1241668],[20.1817362,46.1601137],[20.1364966,46.1449476],[20.1009667,46.1772756],[20.0636156,46.1437275],[20.0346142,46.1458888],[20.0158072,46.1768354],[19.9354075,46.1764243],[19.8533469,46.1500005],[19.8179747,46.1281652],[19.7585403,46.1479754],[19.6982054,46.1879317],[19.6827672,46.1800388],[19.661508,46.1904394],[19.6317396,46.1692993],[19.5676482,46.179106],[19.5604013,46.1665762],[19.5026585,46.1424492],[19.5271208,46.1210269],[19.4645033,46.0953827],[19.4665828,46.0820437],[19.4160037,46.0460453],[19.3803957,46.0358749],[19.3640923,46.0522965],[19.2819012,46.0148048],[19.2965348,45.9881173],[19.2856472,45.9968981],[19.1479857,45.9963445],[19.1338422,46.0370993],[19.104873,46.0401673],[19.0660427,46.0001999],[19.0796791,45.9636376],[19.0059803,45.9590674],[19.0092745,45.9236559],[18.9061334,45.9353801],[18.8794572,45.9166827],[18.8647137,45.9208493],[18.8685629,45.9113361],[18.8276792,45.9051714],[18.8220041,45.9145893],[18.8075092,45.9036055],[18.809247,45.8796189],[18.7956242,45.8784488],[18.7048857,45.9181883],[18.6700246,45.9108439],[18.6596602,45.9168934],[18.6651348,45.899279],[18.6412808,45.8890396],[18.6550179,45.8742393],[18.6277704,45.8733782],[18.6148449,45.8531438],[18.6236656,45.8398531],[18.5732391,45.8137578],[18.5749849,45.8004344],[18.559716,45.8037961],[18.5223504,45.7826858],[18.4906706,45.7947167],[18.4821905,45.7655032],[18.4562828,45.7695229],[18.4450763,45.7605195],[18.446853,45.737128],[18.40763,45.7397119],[18.3918949,45.7616983],[18.3642257,45.7729364],[18.3394214,45.7471605],[18.2968157,45.7612196],[18.2440473,45.7612305],[18.2307311,45.7790328],[18.1908702,45.7878759],[18.1681939,45.7762712],[18.1246514,45.7896277],[18.1068067,45.7708256],[18.0818922,45.7645205],[17.9958808,45.7957311],[17.9302095,45.7863301],[17.9066757,45.7925692],[17.8653145,45.7670064],[17.8262748,45.8099957],[17.8089784,45.8040989],[17.7809054,45.8174884],[17.7603399,45.811923],[17.7408624,45.8295975],[17.6632915,45.8381849],[17.6276211,45.8979446],[17.5700676,45.9358204],[17.4378254,45.9503823],[17.4258964,45.9272681],[17.4108059,45.9399665],[17.392149,45.9302149],[17.3828713,45.9475733],[17.3476208,45.9423413],[17.3438769,45.9605329],[17.3537711,45.9525011],[17.3905375,45.9581914],[17.387423,45.9661823],[17.3583539,45.9642737],[17.3754852,45.9686921],[17.3751895,45.9881054],[17.3635685,45.9915442],[17.3567202,45.9735836],[17.3339583,45.9960781],[17.3319847,45.9728948],[17.3129974,45.9665347],[17.323647,45.9887776],[17.2987653,45.9838652],[17.3041996,46.0021128],[17.2579726,46.0110256],[17.29632,46.0285169],[17.2541514,46.030005],[17.270955,46.0567055],[17.2324767,46.0592034],[17.2525145,46.0664725],[17.2313144,46.0790345],[17.2019916,46.0765488],[17.2331299,46.0989644],[17.2104017,46.1001693],[17.2129734,46.113855],[17.175927,46.1084583],[17.1743424,46.1287608],[17.1865197,46.1332308],[17.1810983,46.1505485],[17.1562307,46.1585819],[17.1592857,46.1696818],[17.1261012,46.1684495],[17.1227409,46.1789791],[17.0752482,46.1889531],[17.0661614,46.2022984],[16.9735401,46.2251982],[16.973954,46.2431113],[16.9504085,46.2415285],[16.8862356,46.2814598],[16.8713682,46.3252767],[16.8802109,46.3356966],[16.8615374,46.3452401],[16.8656232,46.3556489],[16.8521959,46.3517189],[16.8498589,46.3626245],[16.8352859,46.3638195],[16.8376499,46.3748032],[16.8261732,46.3670994],[16.7933444,46.387385],[16.7592072,46.3776563],[16.7298672,46.40149],[16.7182119,46.3898704],[16.6772872,46.4494536],[16.6631785,46.4486958],[16.6663732,46.4582995],[16.6187915,46.4619875],[16.604468,46.4760773],[16.5235997,46.5053761],[16.5325768,46.5314027],[16.5176728,46.5363516],[16.5084107,46.5652692],[16.4829969,46.5660383],[16.4834008,46.5786011],[16.4455713,46.610952],[16.4248583,46.6131645],[16.385941,46.6442485],[16.3915424,46.6637257],[16.4198454,46.6584771],[16.4286335,46.6939737],[16.3689211,46.7040082],[16.3798266,46.7153869],[16.3710856,46.7222945],[16.3570587,46.7142387],[16.3185954,46.7541449],[16.3305417,46.7752119],[16.3121626,46.7780033],[16.3127666,46.797314],[16.3406373,46.8051851],[16.3508404,46.8300552],[16.3403309,46.8468762],[16.3015007,46.8595142],[16.2913867,46.8728341],[16.2332296,46.8766702],[16.1560866,46.8537074],[16.126571,46.8569079],[16.1139147,46.8691038]]],"terms_url":"http://www.fomi.hu/","terms_text":"Földmérési és Távérzékelési Intézet"},{"id":"FOMI_2005","name":"FÖMI ortofotó 2005","type":"tms","template":"http://e.tile.openstreetmap.hu/ortofoto2005/{zoom}/{x}/{y}.jpg","description":"Hungary","scaleExtent":[0,17],"polygon":[[[16.1139147,46.8691038],[16.1789749,46.90662],[16.2000429,46.9415079],[16.2217547,46.9355441],[16.2462784,46.9463851],[16.2553226,46.9642125],[16.2764694,46.9626082],[16.290583,47.0139849],[16.3016199,46.9992329],[16.3414618,46.9965225],[16.3505162,47.0106313],[16.3734016,46.9985929],[16.412765,47.00475],[16.4332705,46.9927417],[16.4478119,47.003893],[16.479997,46.9941169],[16.5121988,47.0011695],[16.4635584,47.0322699],[16.4478586,47.0227481],[16.439123,47.029663],[16.445673,47.038872],[16.520323,47.056103],[16.473213,47.0736169],[16.4637199,47.09392],[16.500798,47.110058],[16.500035,47.123295],[16.5295349,47.1287419],[16.5171609,47.1496938],[16.454951,47.1425878],[16.4648728,47.1683349],[16.4555643,47.1875584],[16.4305559,47.1847022],[16.4195013,47.1949147],[16.4189215,47.2107114],[16.4371293,47.2097043],[16.4426335,47.2337117],[16.4313127,47.2527554],[16.4671512,47.2531652],[16.4892319,47.2798885],[16.4646338,47.3338455],[16.4337002,47.3528101],[16.458513,47.3670496],[16.4454619,47.4070195],[16.4831657,47.4093628],[16.4963821,47.3892659],[16.5170941,47.4100218],[16.5749054,47.4054243],[16.5807291,47.4191699],[16.661847,47.455595],[16.6706419,47.47422],[16.6523395,47.500342],[16.6895619,47.510161],[16.7147797,47.540199],[16.663545,47.567733],[16.673199,47.6049544],[16.6595343,47.6061018],[16.652758,47.622852],[16.6314207,47.6283176],[16.5739108,47.619667],[16.5147382,47.6461964],[16.4967504,47.6393149],[16.425464,47.6621679],[16.4437449,47.674205],[16.4480507,47.6964725],[16.4746984,47.6811576],[16.4872245,47.6979767],[16.5521729,47.7225519],[16.5363779,47.736785],[16.5479799,47.751544],[16.6095193,47.7603722],[16.6344148,47.7590843],[16.65729,47.7414879],[16.7209405,47.7353565],[16.7534062,47.6828165],[16.8301587,47.681058],[16.8394284,47.7045139],[16.8668943,47.7211462],[16.876679,47.6876452],[17.0937421,47.7077706],[17.0706562,47.7285366],[17.0516019,47.7938499],[17.0749479,47.8084997],[17.047139,47.8285635],[17.0519452,47.8377691],[17.0105513,47.8581765],[17.0163878,47.8673325],[17.0857537,47.8746239],[17.113171,47.9271605],[17.0917133,47.9342916],[17.1183782,47.9601083],[17.094657,47.9708775],[17.2010289,48.019992],[17.241769,48.0224651],[17.257955,47.998655],[17.334651,47.993125],[17.4029929,47.947849],[17.4539199,47.8852579],[17.5267369,47.865509],[17.5675779,47.8151289],[17.608402,47.8218859],[17.7085789,47.756678],[17.7798739,47.739487],[17.8660959,47.74575],[17.9001292,47.7392633],[17.946867,47.744668],[17.9708709,47.7578392],[18.0044103,47.7463402],[18.0380583,47.7576812],[18.2958774,47.7314616],[18.4540681,47.7651226],[18.4931553,47.7527552],[18.5590761,47.7659963],[18.6460866,47.7590921],[18.7260691,47.7890411],[18.7411784,47.8138245],[18.7920013,47.8230869],[18.8485417,47.8167221],[18.855876,47.826077],[18.828014,47.834291],[18.8135749,47.85555],[18.76353,47.8716049],[18.756858,47.896838],[18.776746,47.955092],[18.7552499,47.9763469],[18.8157429,47.993442],[18.819998,48.039676],[18.833268,48.048239],[18.8749364,48.0470707],[18.886674,48.058682],[18.9089819,48.051139],[18.9439039,48.058865],[18.9816099,48.0536009],[19.0148639,48.078179],[19.0585249,48.0573529],[19.0843619,48.072781],[19.107402,48.065596],[19.1352889,48.074146],[19.2413679,48.0536529],[19.2557819,48.0715559],[19.3031119,48.088711],[19.3865969,48.091914],[19.400018,48.082304],[19.454053,48.101436],[19.467354,48.083933],[19.4944199,48.109906],[19.492377,48.1396639],[19.5128219,48.154663],[19.504518,48.173443],[19.528967,48.190358],[19.526044,48.20313],[19.577502,48.2160149],[19.6308263,48.2500725],[19.6445239,48.2391719],[19.669857,48.239212],[19.691219,48.203894],[19.721125,48.201473],[19.74618,48.2165119],[19.7871629,48.19253],[19.7987329,48.19482],[19.8052829,48.183733],[19.782415,48.165039],[19.794812,48.153529],[19.821331,48.169081],[19.8452819,48.162742],[19.8551729,48.178431],[19.8601309,48.169409],[19.898745,48.1663119],[19.9145359,48.146863],[19.898298,48.1249019],[19.937383,48.131118],[19.9743939,48.1660049],[19.988706,48.1621679],[20.029038,48.1776849],[20.049449,48.1671999],[20.0729859,48.179606],[20.0700369,48.1917019],[20.1340909,48.225182],[20.1331879,48.253982],[20.206162,48.250979],[20.2038299,48.261906],[20.228466,48.262779],[20.2349469,48.279933],[20.286858,48.26164],[20.3257109,48.272794],[20.3374649,48.301667],[20.3656579,48.316606],[20.384077,48.3511809],[20.4098349,48.365857],[20.402532,48.382565],[20.4205349,48.403858],[20.416228,48.418536],[20.507929,48.489363],[20.5065069,48.534415],[20.537471,48.527878],[20.5464939,48.544292],[20.586595,48.535759],[20.6538739,48.561413],[20.836359,48.58284],[20.8378,48.57421],[20.8504359,48.5816329],[20.8453301,48.5665046],[20.8681549,48.551818],[20.922323,48.559453],[20.9346349,48.538341],[20.955882,48.533963],[20.9561979,48.521666],[20.9815849,48.5177669],[21.0151139,48.532313],[21.0663209,48.525894],[21.1174479,48.4910549],[21.1608749,48.521499],[21.179634,48.518232],[21.221061,48.537497],[21.305488,48.5222489],[21.313377,48.550841],[21.326875,48.554129],[21.319384,48.561201],[21.4154499,48.558951],[21.4226649,48.578821],[21.4406099,48.585104],[21.514091,48.551065],[21.5420199,48.508395],[21.6139329,48.509416],[21.6201879,48.469826],[21.663549,48.417961],[21.6645609,48.392164],[21.7017409,48.380695],[21.711871,48.357617],[21.8174139,48.332787],[21.8352029,48.3346409],[21.837213,48.363253],[21.8842979,48.356047],[21.8848429,48.367539],[21.897883,48.36256],[21.8997959,48.3702229],[21.9281859,48.3615969],[21.9268059,48.370899],[21.949198,48.378728],[21.994463,48.377323],[22.0213259,48.392749],[22.0546049,48.377528],[22.0764859,48.387241],[22.086743,48.371564],[22.1359089,48.380519],[22.131056,48.3912329],[22.152768,48.3962409],[22.1561913,48.4093076],[22.2125722,48.4256468],[22.2371405,48.4100396],[22.2654858,48.4098675],[22.2398761,48.3870055],[22.2675722,48.3611612],[22.3178106,48.3545437],[22.3132861,48.3250712],[22.3372944,48.3079113],[22.3384267,48.2792074],[22.3847547,48.2339632],[22.4006407,48.249198],[22.4328384,48.2525166],[22.456386,48.2423109],[22.4899029,48.2534237],[22.4972201,48.2395546],[22.5161491,48.237965],[22.5311088,48.2094282],[22.5711442,48.1961428],[22.5616362,48.1816066],[22.5982449,48.144756],[22.5902763,48.1073414],[22.6754492,48.091997],[22.7347192,48.119848],[22.7576242,48.1200599],[22.7703914,48.1090162],[22.772319,48.1218742],[22.8027688,48.1221112],[22.8025285,48.1070813],[22.8254256,48.1175119],[22.8364365,48.080249],[22.8611284,48.0750312],[22.8677955,48.0524256],[22.8820424,48.0548053],[22.8659692,48.0113165],[22.835562,47.9905988],[22.8407599,47.9813636],[22.8725729,47.9752683],[22.8697274,47.9659593],[22.8915652,47.9672446],[22.897435,47.9540629],[22.8473299,47.9077579],[22.7928135,47.8908586],[22.7586924,47.8941446],[22.77775,47.8422508],[22.7136344,47.8360928],[22.6801938,47.7877527],[22.6111171,47.7717455],[22.5490018,47.7722246],[22.4812121,47.8108886],[22.4513078,47.803389],[22.4313319,47.7398119],[22.3566167,47.7486206],[22.3177714,47.7660887],[22.3176236,47.7433657],[22.2851369,47.7292757],[22.264325,47.7310675],[22.2589955,47.6979057],[22.2306796,47.693196],[22.1796501,47.5916115],[22.1289245,47.5978984],[22.0942787,47.5583628],[22.0782587,47.5621299],[22.0534529,47.5474795],[22.0712176,47.5380742],[22.0617872,47.5288029],[22.0451278,47.5398919],[22.0367222,47.5326653],[22.0071886,47.48362],[22.0327909,47.4508372],[22.0238835,47.3908631],[22.0119849,47.3758016],[21.9627373,47.381053],[21.9382461,47.3725317],[21.8777922,47.2857763],[21.8872845,47.2730473],[21.8534909,47.2397622],[21.8580662,47.1873597],[21.8124804,47.1667511],[21.7924092,47.1059751],[21.7268258,47.0983882],[21.6976037,47.057915],[21.6504151,47.0408303],[21.6888701,47.0019977],[21.6678744,46.9712337],[21.6814917,46.9652089],[21.6381964,46.9330487],[21.5984455,46.9274708],[21.6142857,46.8867275],[21.6016694,46.8668202],[21.520328,46.8373749],[21.5186086,46.8000703],[21.4831761,46.7650246],[21.5263389,46.7393249],[21.529369,46.7209721],[21.4923253,46.6859652],[21.4728438,46.6959075],[21.4299047,46.693937],[21.4309553,46.6781367],[21.4546661,46.660863],[21.4162375,46.6426231],[21.4097959,46.6218052],[21.3657038,46.6379501],[21.3300499,46.6318155],[21.3139733,46.617666],[21.3012351,46.5908672],[21.3207905,46.5828562],[21.2743045,46.5407362],[21.2600254,46.5021583],[21.2744188,46.4767333],[21.2964506,46.4762973],[21.3174343,46.4507288],[21.2895176,46.4154784],[21.2963256,46.4069601],[21.2250116,46.4136899],[21.2064214,46.4033825],[21.1992563,46.3479034],[21.1762269,46.3357664],[21.180497,46.3044494],[21.1155437,46.3018529],[21.1030549,46.2624637],[21.0708792,46.2539014],[21.0660827,46.2429394],[21.0366237,46.2480392],[21.0246723,46.2665329],[20.960817,46.2623039],[20.9465849,46.2793024],[20.9250701,46.2766191],[20.9218133,46.2618129],[20.8732713,46.2877555],[20.7756538,46.2759602],[20.7490474,46.2508489],[20.7618619,46.204563],[20.727401,46.2077485],[20.7341052,46.1939355],[20.7140487,46.1660531],[20.6843592,46.1447802],[20.6549178,46.1497739],[20.6394471,46.1267602],[20.5450486,46.1790935],[20.5014839,46.190334],[20.4949436,46.1709908],[20.4592293,46.1428837],[20.3975133,46.1574709],[20.3685325,46.1528554],[20.3557074,46.1696256],[20.2968136,46.1521542],[20.2549024,46.1158522],[20.2484757,46.1300956],[20.2330132,46.1241668],[20.1817362,46.1601137],[20.1364966,46.1449476],[20.1009667,46.1772756],[20.0636156,46.1437275],[20.0346142,46.1458888],[20.0158072,46.1768354],[19.9354075,46.1764243],[19.8533469,46.1500005],[19.8179747,46.1281652],[19.7585403,46.1479754],[19.6982054,46.1879317],[19.6827672,46.1800388],[19.661508,46.1904394],[19.6317396,46.1692993],[19.5676482,46.179106],[19.5604013,46.1665762],[19.5026585,46.1424492],[19.5271208,46.1210269],[19.4645033,46.0953827],[19.4665828,46.0820437],[19.4160037,46.0460453],[19.3803957,46.0358749],[19.3640923,46.0522965],[19.2819012,46.0148048],[19.2965348,45.9881173],[19.2856472,45.9968981],[19.1479857,45.9963445],[19.1338422,46.0370993],[19.104873,46.0401673],[19.0660427,46.0001999],[19.0796791,45.9636376],[19.0059803,45.9590674],[19.0092745,45.9236559],[18.9061334,45.9353801],[18.8794572,45.9166827],[18.8647137,45.9208493],[18.8685629,45.9113361],[18.8276792,45.9051714],[18.8220041,45.9145893],[18.8075092,45.9036055],[18.809247,45.8796189],[18.7956242,45.8784488],[18.7048857,45.9181883],[18.6700246,45.9108439],[18.6596602,45.9168934],[18.6651348,45.899279],[18.6412808,45.8890396],[18.6550179,45.8742393],[18.6277704,45.8733782],[18.6148449,45.8531438],[18.6236656,45.8398531],[18.5732391,45.8137578],[18.5749849,45.8004344],[18.559716,45.8037961],[18.5223504,45.7826858],[18.4906706,45.7947167],[18.4821905,45.7655032],[18.4562828,45.7695229],[18.4450763,45.7605195],[18.446853,45.737128],[18.40763,45.7397119],[18.3918949,45.7616983],[18.3642257,45.7729364],[18.3394214,45.7471605],[18.2968157,45.7612196],[18.2440473,45.7612305],[18.2307311,45.7790328],[18.1908702,45.7878759],[18.1681939,45.7762712],[18.1246514,45.7896277],[18.1068067,45.7708256],[18.0818922,45.7645205],[17.9958808,45.7957311],[17.9302095,45.7863301],[17.9066757,45.7925692],[17.8653145,45.7670064],[17.8262748,45.8099957],[17.8089784,45.8040989],[17.7809054,45.8174884],[17.7603399,45.811923],[17.7408624,45.8295975],[17.6632915,45.8381849],[17.6276211,45.8979446],[17.5700676,45.9358204],[17.4378254,45.9503823],[17.4258964,45.9272681],[17.4108059,45.9399665],[17.392149,45.9302149],[17.3828713,45.9475733],[17.3476208,45.9423413],[17.3438769,45.9605329],[17.3537711,45.9525011],[17.3905375,45.9581914],[17.387423,45.9661823],[17.3583539,45.9642737],[17.3754852,45.9686921],[17.3751895,45.9881054],[17.3635685,45.9915442],[17.3567202,45.9735836],[17.3339583,45.9960781],[17.3319847,45.9728948],[17.3129974,45.9665347],[17.323647,45.9887776],[17.2987653,45.9838652],[17.3041996,46.0021128],[17.2579726,46.0110256],[17.29632,46.0285169],[17.2541514,46.030005],[17.270955,46.0567055],[17.2324767,46.0592034],[17.2525145,46.0664725],[17.2313144,46.0790345],[17.2019916,46.0765488],[17.2331299,46.0989644],[17.2104017,46.1001693],[17.2129734,46.113855],[17.175927,46.1084583],[17.1743424,46.1287608],[17.1865197,46.1332308],[17.1810983,46.1505485],[17.1562307,46.1585819],[17.1592857,46.1696818],[17.1261012,46.1684495],[17.1227409,46.1789791],[17.0752482,46.1889531],[17.0661614,46.2022984],[16.9735401,46.2251982],[16.973954,46.2431113],[16.9504085,46.2415285],[16.8862356,46.2814598],[16.8713682,46.3252767],[16.8802109,46.3356966],[16.8615374,46.3452401],[16.8656232,46.3556489],[16.8521959,46.3517189],[16.8498589,46.3626245],[16.8352859,46.3638195],[16.8376499,46.3748032],[16.8261732,46.3670994],[16.7933444,46.387385],[16.7592072,46.3776563],[16.7298672,46.40149],[16.7182119,46.3898704],[16.6772872,46.4494536],[16.6631785,46.4486958],[16.6663732,46.4582995],[16.6187915,46.4619875],[16.604468,46.4760773],[16.5235997,46.5053761],[16.5325768,46.5314027],[16.5176728,46.5363516],[16.5084107,46.5652692],[16.4829969,46.5660383],[16.4834008,46.5786011],[16.4455713,46.610952],[16.4248583,46.6131645],[16.385941,46.6442485],[16.3915424,46.6637257],[16.4198454,46.6584771],[16.4286335,46.6939737],[16.3689211,46.7040082],[16.3798266,46.7153869],[16.3710856,46.7222945],[16.3570587,46.7142387],[16.3185954,46.7541449],[16.3305417,46.7752119],[16.3121626,46.7780033],[16.3127666,46.797314],[16.3406373,46.8051851],[16.3508404,46.8300552],[16.3403309,46.8468762],[16.3015007,46.8595142],[16.2913867,46.8728341],[16.2332296,46.8766702],[16.1560866,46.8537074],[16.126571,46.8569079],[16.1139147,46.8691038]]],"terms_url":"http://www.fomi.hu/","terms_text":"Földmérési és Távérzékelési Intézet"},{"id":"FR-BAN","name":"FR-BAN","type":"tms","template":"http://{switch:a,b,c}.layers.openstreetmap.fr/bano/{zoom}/{x}/{y}.png","description":"French address registry or Base Adresses Nationale","scaleExtent":[12,20],"polygon":[[[8.3247852,49.0891892],[6.1566882,49.6167369],[4.8666714,50.2126152],[2.4937064,51.1761675],[1.3121526,50.9324682],[1.2659981,50.1877492],[0.1121369,49.8258592],[-0.3494075,49.4312336],[-1.0232625,49.4852345],[-1.3278818,49.7901162],[-2.1032765,49.7901162],[-1.6232703,48.7420657],[-3.1002126,48.9728514],[-5.1125465,48.6811558],[-5.3525496,48.4367783],[-4.5984193,47.7194959],[-2.555398,47.0232784],[-2.4738077,46.6638823],[-1.6676954,46.1055717],[-1.334807,45.5141125],[-1.4914604,44.1627003],[-1.9940567,43.3708146],[-0.956228,42.7364747],[2.2029487,42.2841894],[3.2342502,42.5444129],[3.2407774,43.1140543],[4.0436261,43.3280964],[6.4325902,42.808345],[7.6270723,43.5934102],[7.8163619,44.1720643],[7.0396221,44.41967],[7.268075,45.4958141],[7.1244761,46.2140775],[6.5631347,46.771283],[7.6571492,47.59128],[7.6527839,47.5941813],[7.6224698,47.5776739],[7.6047297,47.578221],[7.5877054,47.5901532],[7.521558,47.65161],[7.503992,47.70235],[7.520958,47.77685],[7.557124,47.84839],[7.549463,47.879205],[7.574615,47.93028],[7.613179,47.96804],[7.611904,47.9871],[7.5612401,48.0383618],[7.574915,48.1258],[7.595338,48.15977],[7.633047,48.19717],[7.662748,48.22473],[7.684659,48.30305],[7.763463,48.49158],[7.8004602,48.5125977],[7.799582,48.5878],[7.834088,48.64439],[7.9121073,48.6889897],[7.9672295,48.7571585],[8.020692,48.78879],[8.043024,48.7956],[8.0864658,48.8130551],[8.1364418,48.8978239],[8.1970586,48.96021],[8.2816129,48.9948995],[8.2996723,49.025966],[8.3124269,49.0599642],[8.3247852,49.0891892]],[[9.3609615,43.1345098],[8.4393174,42.48439],[8.4836272,41.8175373],[8.8469677,41.3768281],[9.2058772,41.3136241],[9.48946,41.5461776],[9.6356823,42.1994563],[9.6046655,42.901254],[9.3609615,43.1345098]]],"terms_url":"https://wiki.openstreetmap.org/wiki/WikiProject_France/WikiProject_Base_Adresses_Nationale_Ouverte_(BANO)","terms_text":"Tiles © cquest@Openstreetmap France, data © OpenStreetMap contributors, ODBL"},{"id":"FR-Cadastre","name":"FR-Cadastre","type":"tms","template":"http://tms.cadastre.openstreetmap.fr/*/tout/{zoom}/{x}/{y}.png","description":"French land registry","scaleExtent":[12,20],"polygon":[[[8.3247852,49.0891892],[6.1566882,49.6167369],[4.8666714,50.2126152],[2.4937064,51.1761675],[1.3121526,50.9324682],[1.2659981,50.1877492],[0.1121369,49.8258592],[-0.3494075,49.4312336],[-1.0232625,49.4852345],[-1.3278818,49.7901162],[-2.1032765,49.7901162],[-1.6232703,48.7420657],[-3.1002126,48.9728514],[-5.1125465,48.6811558],[-5.3525496,48.4367783],[-4.5984193,47.7194959],[-2.555398,47.0232784],[-2.4738077,46.6638823],[-1.6676954,46.1055717],[-1.334807,45.5141125],[-1.4914604,44.1627003],[-1.9940567,43.3708146],[-0.956228,42.7364747],[2.2029487,42.2841894],[3.2342502,42.5444129],[3.2407774,43.1140543],[4.0436261,43.3280964],[6.4325902,42.808345],[7.6270723,43.5934102],[7.8163619,44.1720643],[7.0396221,44.41967],[7.268075,45.4958141],[7.1244761,46.2140775],[6.5631347,46.771283],[7.6571492,47.59128],[7.6527839,47.5941813],[7.6224698,47.5776739],[7.6047297,47.578221],[7.5877054,47.5901532],[7.521558,47.65161],[7.503992,47.70235],[7.520958,47.77685],[7.557124,47.84839],[7.549463,47.879205],[7.574615,47.93028],[7.613179,47.96804],[7.611904,47.9871],[7.5612401,48.0383618],[7.574915,48.1258],[7.595338,48.15977],[7.633047,48.19717],[7.662748,48.22473],[7.684659,48.30305],[7.763463,48.49158],[7.8004602,48.5125977],[7.799582,48.5878],[7.834088,48.64439],[7.9121073,48.6889897],[7.9672295,48.7571585],[8.020692,48.78879],[8.043024,48.7956],[8.0864658,48.8130551],[8.1364418,48.8978239],[8.1970586,48.96021],[8.2816129,48.9948995],[8.2996723,49.025966],[8.3124269,49.0599642],[8.3247852,49.0891892]],[[9.3609615,43.1345098],[8.4393174,42.48439],[8.4836272,41.8175373],[8.8469677,41.3768281],[9.2058772,41.3136241],[9.48946,41.5461776],[9.6356823,42.1994563],[9.6046655,42.901254],[9.3609615,43.1345098]]],"terms_url":"http://wiki.openstreetmap.org/wiki/WikiProject_Cadastre_Fran%C3%A7ais/Conditions_d%27utilisation","terms_text":"cadastre-dgi-fr source : Direction Générale des Impôts - Cadastre. Mise à jour : 2015"},{"id":"Freemap.sk-Car","name":"Freemap.sk Car","type":"tms","template":"http://t{switch:1,2,3,4}.freemap.sk/A/{zoom}/{x}/{y}.jpeg","scaleExtent":[8,16],"polygon":[[[19.83682,49.25529],[19.80075,49.42385],[19.60437,49.48058],[19.49179,49.63961],[19.21831,49.52604],[19.16778,49.42521],[19.00308,49.42236],[18.97611,49.5308],[18.54685,49.51425],[18.31432,49.33818],[18.15913,49.2961],[18.05564,49.11134],[17.56396,48.84938],[17.17929,48.88816],[17.058,48.81105],[16.90426,48.61947],[16.79685,48.38561],[17.06762,48.01116],[17.32787,47.97749],[17.51699,47.82535],[17.74776,47.73093],[18.29515,47.72075],[18.67959,47.75541],[18.89755,47.81203],[18.79463,47.88245],[18.84318,48.04046],[19.46212,48.05333],[19.62064,48.22938],[19.89585,48.09387],[20.33766,48.2643],[20.55395,48.52358],[20.82335,48.55714],[21.10271,48.47096],[21.45863,48.55513],[21.74536,48.31435],[22.15293,48.37179],[22.61255,49.08914],[22.09997,49.23814],[21.9686,49.36363],[21.6244,49.46989],[21.06873,49.46402],[20.94336,49.31088],[20.73052,49.44006],[20.22804,49.41714],[20.05234,49.23052],[19.83682,49.25529]]],"terms_text":"Copyright ©2007-2012 Freemap Slovakia (www.freemap.sk). Some rights reserved."},{"id":"Freemap.sk-Cyclo","name":"Freemap.sk Cyclo","type":"tms","template":"http://t{switch:1,2,3,4}.freemap.sk/C/{zoom}/{x}/{y}.jpeg","scaleExtent":[8,16],"polygon":[[[19.83682,49.25529],[19.80075,49.42385],[19.60437,49.48058],[19.49179,49.63961],[19.21831,49.52604],[19.16778,49.42521],[19.00308,49.42236],[18.97611,49.5308],[18.54685,49.51425],[18.31432,49.33818],[18.15913,49.2961],[18.05564,49.11134],[17.56396,48.84938],[17.17929,48.88816],[17.058,48.81105],[16.90426,48.61947],[16.79685,48.38561],[17.06762,48.01116],[17.32787,47.97749],[17.51699,47.82535],[17.74776,47.73093],[18.29515,47.72075],[18.67959,47.75541],[18.89755,47.81203],[18.79463,47.88245],[18.84318,48.04046],[19.46212,48.05333],[19.62064,48.22938],[19.89585,48.09387],[20.33766,48.2643],[20.55395,48.52358],[20.82335,48.55714],[21.10271,48.47096],[21.45863,48.55513],[21.74536,48.31435],[22.15293,48.37179],[22.61255,49.08914],[22.09997,49.23814],[21.9686,49.36363],[21.6244,49.46989],[21.06873,49.46402],[20.94336,49.31088],[20.73052,49.44006],[20.22804,49.41714],[20.05234,49.23052],[19.83682,49.25529]]],"terms_text":"Copyright ©2007-2012 Freemap Slovakia (www.freemap.sk). Some rights reserved."},{"id":"Freemap.sk-Hiking","name":"Freemap.sk Hiking","type":"tms","template":"http://t{switch:1,2,3,4}.freemap.sk/T/{zoom}/{x}/{y}.jpeg","scaleExtent":[8,16],"polygon":[[[19.83682,49.25529],[19.80075,49.42385],[19.60437,49.48058],[19.49179,49.63961],[19.21831,49.52604],[19.16778,49.42521],[19.00308,49.42236],[18.97611,49.5308],[18.54685,49.51425],[18.31432,49.33818],[18.15913,49.2961],[18.05564,49.11134],[17.56396,48.84938],[17.17929,48.88816],[17.058,48.81105],[16.90426,48.61947],[16.79685,48.38561],[17.06762,48.01116],[17.32787,47.97749],[17.51699,47.82535],[17.74776,47.73093],[18.29515,47.72075],[18.67959,47.75541],[18.89755,47.81203],[18.79463,47.88245],[18.84318,48.04046],[19.46212,48.05333],[19.62064,48.22938],[19.89585,48.09387],[20.33766,48.2643],[20.55395,48.52358],[20.82335,48.55714],[21.10271,48.47096],[21.45863,48.55513],[21.74536,48.31435],[22.15293,48.37179],[22.61255,49.08914],[22.09997,49.23814],[21.9686,49.36363],[21.6244,49.46989],[21.06873,49.46402],[20.94336,49.31088],[20.73052,49.44006],[20.22804,49.41714],[20.05234,49.23052],[19.83682,49.25529]]],"terms_text":"Copyright ©2007-2012 Freemap Slovakia (www.freemap.sk). Some rights reserved."},{"id":"Freemap.sk-Ski","name":"Freemap.sk Ski","type":"tms","template":"http://t{switch:1,2,3,4}.freemap.sk/K/{zoom}/{x}/{y}.jpeg","scaleExtent":[8,16],"polygon":[[[19.83682,49.25529],[19.80075,49.42385],[19.60437,49.48058],[19.49179,49.63961],[19.21831,49.52604],[19.16778,49.42521],[19.00308,49.42236],[18.97611,49.5308],[18.54685,49.51425],[18.31432,49.33818],[18.15913,49.2961],[18.05564,49.11134],[17.56396,48.84938],[17.17929,48.88816],[17.058,48.81105],[16.90426,48.61947],[16.79685,48.38561],[17.06762,48.01116],[17.32787,47.97749],[17.51699,47.82535],[17.74776,47.73093],[18.29515,47.72075],[18.67959,47.75541],[18.89755,47.81203],[18.79463,47.88245],[18.84318,48.04046],[19.46212,48.05333],[19.62064,48.22938],[19.89585,48.09387],[20.33766,48.2643],[20.55395,48.52358],[20.82335,48.55714],[21.10271,48.47096],[21.45863,48.55513],[21.74536,48.31435],[22.15293,48.37179],[22.61255,49.08914],[22.09997,49.23814],[21.9686,49.36363],[21.6244,49.46989],[21.06873,49.46402],[20.94336,49.31088],[20.73052,49.44006],[20.22804,49.41714],[20.05234,49.23052],[19.83682,49.25529]]],"terms_text":"Copyright ©2007-2012 Freemap Slovakia (www.freemap.sk). Some rights reserved."},{"id":"Geodatastyrelsen_Denmark","name":"Geodatastyrelsen (Denmark)","type":"tms","template":"http://osmtools.septima.dk/mapproxy/tiles/1.0.0/kortforsyningen_ortoforaar/EPSG3857/{zoom}/{x}/{y}.jpeg","scaleExtent":[0,21],"polygon":[[[8.3743941,54.9551655],[8.3683809,55.4042149],[8.2103997,55.4039795],[8.2087314,55.4937345],[8.0502655,55.4924731],[8.0185123,56.7501399],[8.1819161,56.7509948],[8.1763274,57.0208898],[8.3413329,57.0219872],[8.3392467,57.1119574],[8.5054433,57.1123212],[8.5033923,57.2020499],[9.3316304,57.2027636],[9.3319079,57.2924835],[9.4978864,57.2919578],[9.4988593,57.3820608],[9.6649749,57.3811615],[9.6687295,57.5605591],[9.8351961,57.5596265],[9.8374896,57.6493322],[10.1725726,57.6462818],[10.1754245,57.7367768],[10.5118282,57.7330269],[10.5152095,57.8228945],[10.6834853,57.8207722],[10.6751613,57.6412021],[10.5077045,57.6433097],[10.5039992,57.5535088],[10.671038,57.5514113],[10.6507805,57.1024538],[10.4857673,57.1045138],[10.4786236,56.9249051],[10.3143981,56.9267573],[10.3112341,56.8369269],[10.4750295,56.83509],[10.4649016,56.5656681],[10.9524239,56.5589761],[10.9479249,56.4692243],[11.1099335,56.4664675],[11.1052639,56.376833],[10.9429901,56.3795284],[10.9341235,56.1994768],[10.7719685,56.2020244],[10.7694751,56.1120103],[10.6079695,56.1150259],[10.4466742,56.116717],[10.2865948,56.118675],[10.2831527,56.0281851],[10.4439274,56.0270388],[10.4417713,55.7579243],[10.4334961,55.6693533],[10.743814,55.6646861],[10.743814,55.5712253],[10.8969041,55.5712253],[10.9051793,55.3953852],[11.0613726,55.3812841],[11.0593038,55.1124061],[11.0458567,55.0318621],[11.2030844,55.0247474],[11.2030844,55.117139],[11.0593038,55.1124061],[11.0613726,55.3812841],[11.0789572,55.5712253],[10.8969041,55.5712253],[10.9258671,55.6670198],[10.743814,55.6646861],[10.7562267,55.7579243],[10.4417713,55.7579243],[10.4439274,56.0270388],[10.4466742,56.116717],[10.6079695,56.1150259],[10.6052053,56.0247462],[10.9258671,56.0201215],[10.9197132,55.9309388],[11.0802782,55.92792],[11.0858066,56.0178284],[11.7265047,56.005058],[11.7319981,56.0952142],[12.0540333,56.0871256],[12.0608477,56.1762576],[12.7023469,56.1594405],[12.6611131,55.7114318],[12.9792318,55.7014026],[12.9612912,55.5217294],[12.3268659,55.5412096],[12.3206071,55.4513655],[12.4778226,55.447067],[12.4702432,55.3570479],[12.6269738,55.3523837],[12.6200898,55.2632576],[12.4627339,55.26722],[12.4552949,55.1778223],[12.2987046,55.1822303],[12.2897344,55.0923641],[12.6048608,55.0832904],[12.5872011,54.9036285],[12.2766618,54.9119031],[12.2610181,54.7331602],[12.1070691,54.7378161],[12.0858621,54.4681655],[11.7794953,54.4753579],[11.7837381,54.5654783],[11.1658525,54.5782155],[11.1706443,54.6686508],[10.8617173,54.6733956],[10.8651245,54.7634667],[10.7713646,54.7643888],[10.7707276,54.7372807],[10.7551428,54.7375776],[10.7544039,54.7195666],[10.7389074,54.7197588],[10.7384368,54.7108482],[10.7074486,54.7113045],[10.7041094,54.6756741],[10.5510973,54.6781698],[10.5547184,54.7670245],[10.2423994,54.7705935],[10.2459845,54.8604673],[10.0902268,54.8622134],[10.0873731,54.7723851],[9.1555798,54.7769557],[9.1562752,54.8675369],[8.5321973,54.8663765],[8.531432,54.95516],[8.3743941,54.9551655]],[[11.4577738,56.819554],[11.7849181,56.8127385],[11.7716715,56.6332796],[11.4459621,56.6401087],[11.4577738,56.819554]],[[11.3274736,57.3612962],[11.3161808,57.1818004],[11.1508692,57.1847276],[11.1456628,57.094962],[10.8157703,57.1001693],[10.8290599,57.3695272],[11.3274736,57.3612962]],[[11.5843266,56.2777928],[11.5782882,56.1880397],[11.7392309,56.1845765],[11.7456428,56.2743186],[11.5843266,56.2777928]],[[14.6825922,55.3639405],[14.8395247,55.3565231],[14.8263755,55.2671261],[15.1393406,55.2517359],[15.1532015,55.3410836],[15.309925,55.3330556],[15.295719,55.2437356],[15.1393406,55.2517359],[15.1255631,55.1623802],[15.2815819,55.1544167],[15.2535578,54.9757646],[14.6317464,55.0062496],[14.6825922,55.3639405]]],"terms_url":"http://download.kortforsyningen.dk/content/vilkaar-og-betingelser","terms_text":"Geodatastyrelsen og Danske Kommuner","best":true},{"id":"Geoportal-PL-aerial_image","name":"Geoportal.gov.pl (Orthophotomap)","type":"tms","template":"http://wms.misek.pl/geoportal.orto/tms/{zoom}/{x}/{y}","scaleExtent":[6,24],"polygon":[[[15.9751041,54.3709213],[16.311164,54.5561775],[17.1391878,54.7845723],[18.3448458,54.9022727],[19.6613689,54.4737213],[20.2815206,54.4213456],[21.4663914,54.3406369],[22.7759855,54.3769755],[22.8625989,54.4233613],[23.2956657,54.2678633],[23.5347186,54.0955258],[23.5208604,53.9775182],[23.7183389,53.4629603],[23.9296755,53.1856735],[23.9296755,52.6887269],[23.732197,52.6067497],[23.5658994,52.5878101],[23.2090523,52.3302642],[23.1951942,52.2370089],[23.5035377,52.1860596],[23.6906226,52.0030113],[23.5970802,51.739903],[23.6629063,51.3888562],[23.9366046,50.9827781],[24.1687284,50.8604752],[24.0197534,50.8035823],[24.1098313,50.6610467],[24.0578633,50.4188439],[23.6178674,50.3083403],[22.6824431,49.5163532],[22.7378756,49.2094935],[22.9041733,49.0780441],[22.8625989,48.9940062],[22.6096878,49.0371785],[22.0761495,49.2004392],[21.8474902,49.3721872],[21.3763135,49.4488281],[21.1026153,49.3721872],[20.9120659,49.3022043],[20.6452967,49.3902311],[20.1845136,49.3315641],[20.1186875,49.2004392],[19.9419962,49.1302123],[19.765305,49.2117568],[19.7479823,49.3992506],[19.6024718,49.4150307],[19.5089294,49.5815389],[19.4292451,49.5905232],[19.2317666,49.4150307],[18.9961783,49.387976],[18.9338167,49.4916048],[18.8368097,49.4938552],[18.8021643,49.6623381],[18.6427958,49.7094091],[18.521537,49.8994693],[18.0815412,50.0109209],[17.8875272,49.9886512],[17.7385522,50.0687739],[17.6068999,50.1709584],[17.7454813,50.2153184],[17.710836,50.3017019],[17.4163505,50.2640668],[16.9486384,50.4453265],[16.8932058,50.4033889],[17.0006064,50.3105529],[17.017929,50.2241854],[16.8135215,50.186489],[16.6402948,50.0976742],[16.4324227,50.2862087],[16.1968344,50.4276731],[16.4220291,50.5885165],[16.3388803,50.6632429],[16.2280152,50.6368824],[16.0547884,50.6127057],[15.5732181,50.7641544],[15.2683391,50.8976368],[15.2440873,50.980597],[15.0292862,51.0133036],[15.0015699,50.8582883],[14.8110205,50.8735944],[14.956531,51.0721176],[15.0188926,51.2914636],[14.9392083,51.4601459],[14.7209426,51.5571799],[14.7521234,51.6260562],[14.5996839,51.8427626],[14.70362,52.0733396],[14.5581095,52.2497371],[14.5165351,52.425436],[14.6031485,52.5878101],[14.1146491,52.8208272],[14.152759,52.9733951],[14.3502374,53.0734212],[14.4229927,53.2665624],[14.1977979,53.8734759],[14.2220497,53.9958517],[15.9751041,54.3709213]]],"terms_text":"Copyright © Główny Urząd Geodezji i Kartografii.","best":true},{"id":"IBGE_DF_Addresses","name":"IBGE Distrito Federal","type":"tms","template":"https://api.mapbox.com/styles/v1/wille/cirnnxni1000jg8nfppc8g7pm/tiles/256/{zoom}/{x}/{y}?access_token=pk.eyJ1Ijoid2lsbGUiLCJhIjoicFNVWk5VWSJ9.hluCd0YGvYHNlFi_utWe2g","description":"Addresses data from IBGE","scaleExtent":[0,19],"polygon":[[[-48.2444,-16.0508],[-48.2444,-15.5005],[-47.5695,-15.5005],[-47.5695,-16.0508],[-48.2444,-16.0508]]],"overlay":true},{"id":"IBGE_Setores_Rurais","name":"IBGE Mapa de Setores Rurais","type":"tms","template":"http://{switch:a,b,c}.tiles.mapbox.com/v4/tmpsantos.i00mo1kj/{zoom}/{x}/{y}.png?access_token=pk.eyJ1Ijoib3BlbnN0cmVldG1hcCIsImEiOiJncjlmd0t3In0.DmZsIeOW-3x-C5eX-wAqTw","scaleExtent":[0,14],"polygon":[[[-29.3325,2.335959],[-28.72472,2.031551],[-27.76041,-8.937033],[-27.67249,-22.20839],[-51.11495,-35.46552],[-53.39394,-33.85064],[-53.62553,-33.72493],[-53.62503,-33.15428],[-53.24498,-32.73392],[-53.65747,-32.51873],[-53.8329,-32.16592],[-54.64174,-31.55507],[-55.29638,-31.3429],[-55.57371,-30.99691],[-56.06384,-31.16749],[-56.10468,-30.86436],[-56.86862,-30.20752],[-57.39671,-30.40464],[-57.74384,-30.22142],[-55.83724,-28.16598],[-54.86969,-27.44994],[-53.9016,-27.02998],[-53.74972,-26.25781],[-53.97158,-25.74513],[-54.44723,-25.79609],[-54.67802,-25.64668],[-54.36097,-24.35145],[-54.41679,-24.06527],[-54.64355,-23.94107],[-55.22163,-24.11355],[-55.49138,-24.02797],[-55.71734,-22.68488],[-55.90555,-22.39886],[-56.45255,-22.21731],[-56.8256,-22.4002],[-57.34109,-22.34351],[-58.08472,-22.13075],[-57.95766,-20.99818],[-58.26551,-20.24147],[-58.03577,-19.95871],[-58.23083,-19.75211],[-57.64739,-18.19828],[-57.89356,-17.57377],[-58.16997,-17.53519],[-58.48825,-17.21961],[-58.57691,-16.81466],[-58.45563,-16.42158],[-60.2541,-16.32571],[-60.33481,-15.51483],[-60.67423,-15.1122],[-60.34999,-14.99707],[-60.63603,-13.84119],[-61.07283,-13.62569],[-61.9025,-13.62647],[-62.21395,-13.25048],[-62.80185,-13.10905],[-63.17194,-12.76568],[-63.74229,-12.54071],[-64.32845,-12.59578],[-65.10261,-12.0682],[-65.45781,-11.27865],[-65.41641,-9.838943],[-66.52331,-9.985873],[-67.66452,-10.80093],[-67.99778,-10.75991],[-68.52286,-11.20807],[-69.88988,-11.02776],[-70.30957,-11.1699],[-70.71896,-11.02003],[-70.68128,-9.669083],[-71.27536,-10.08971],[-72.18053,-10.09967],[-72.41623,-9.587397],[-73.29207,-9.454149],[-73.0625,-9.017267],[-73.61432,-8.40982],[-74.09056,-7.527548],[-74.03652,-7.27885],[-73.84718,-7.238285],[-73.78618,-6.774872],[-73.22362,-6.430106],[-73.33719,-6.029736],[-72.93016,-5.038711],[-71.93973,-4.425027],[-70.96802,-4.248294],[-70.79598,-4.064931],[-70.02393,-4.167345],[-69.51025,-1.134089],[-69.70776,-0.567619],[-70.13645,-0.226161],[-70.14083,0.5844],[-69.26594,0.806502],[-69.34226,0.968924],[-69.92481,1.015705],[-69.92343,1.773851],[-68.38511,1.82943],[-68.24848,2.119808],[-67.94571,1.948424],[-67.37696,2.327468],[-67.05751,1.858336],[-67.00579,1.291603],[-66.79967,1.314684],[-66.28683,0.857709],[-65.67671,1.111146],[-65.42494,0.966549],[-65.15671,1.24203],[-64.27483,1.601591],[-64.0486,2.065137],[-63.47236,2.279358],[-64.13446,2.433909],[-64.10005,2.723778],[-64.32628,3.118275],[-64.28142,3.541983],[-64.88451,4.117671],[-64.88064,4.342461],[-64.13653,4.223152],[-63.95465,4.021316],[-63.17706,4.048301],[-62.96093,3.763658],[-62.82024,4.106019],[-62.49922,4.270815],[-61.91181,4.26284],[-61.35393,4.630097],[-61.04904,4.623115],[-60.70452,4.969851],[-60.78709,5.296764],[-60.22457,5.371207],[-59.89857,5.107541],[-59.97549,4.603025],[-59.59676,4.439875],[-59.41942,3.96994],[-59.71017,3.542008],[-59.88955,2.72301],[-59.63006,2.316332],[-59.63382,1.966581],[-59.18812,1.478079],[-58.80545,1.320732],[-58.35933,1.689932],[-57.6,1.803907],[-57.39854,2.065119],[-57.12392,2.128758],[-56.02925,1.949445],[-56.23884,2.263348],[-55.98195,2.628657],[-55.64816,2.519953],[-54.93958,2.682515],[-54.24988,2.25056],[-53.73937,2.473731],[-52.98578,2.280494],[-52.65712,2.564069],[-52.41739,3.22121],[-51.73983,4.119158],[-51.7246,4.556867],[-51.0112,5.522895],[-43.48209,5.335832],[-29.3325,2.335959]]]},{"id":"IBGE_Setores_Urbanos","name":"IBGE Mapa de Setores Urbanos","type":"tms","template":"http://{switch:a,b,c}.tiles.mapbox.com/v4/tmpsantos.hgda0m6h/{zoom}/{x}/{y}.png?access_token=pk.eyJ1Ijoib3BlbnN0cmVldG1hcCIsImEiOiJncjlmd0t3In0.DmZsIeOW-3x-C5eX-wAqTw","scaleExtent":[0,19],"polygon":[[[-29.3325,2.335959],[-28.72472,2.031551],[-27.76041,-8.937033],[-27.67249,-22.20839],[-51.11495,-35.46552],[-53.39394,-33.85064],[-53.62553,-33.72493],[-53.62503,-33.15428],[-53.24498,-32.73392],[-53.65747,-32.51873],[-53.8329,-32.16592],[-54.64174,-31.55507],[-55.29638,-31.3429],[-55.57371,-30.99691],[-56.06384,-31.16749],[-56.10468,-30.86436],[-56.86862,-30.20752],[-57.39671,-30.40464],[-57.74384,-30.22142],[-55.83724,-28.16598],[-54.86969,-27.44994],[-53.9016,-27.02998],[-53.74972,-26.25781],[-53.97158,-25.74513],[-54.44723,-25.79609],[-54.67802,-25.64668],[-54.36097,-24.35145],[-54.41679,-24.06527],[-54.64355,-23.94107],[-55.22163,-24.11355],[-55.49138,-24.02797],[-55.71734,-22.68488],[-55.90555,-22.39886],[-56.45255,-22.21731],[-56.8256,-22.4002],[-57.34109,-22.34351],[-58.08472,-22.13075],[-57.95766,-20.99818],[-58.26551,-20.24147],[-58.03577,-19.95871],[-58.23083,-19.75211],[-57.64739,-18.19828],[-57.89356,-17.57377],[-58.16997,-17.53519],[-58.48825,-17.21961],[-58.57691,-16.81466],[-58.45563,-16.42158],[-60.2541,-16.32571],[-60.33481,-15.51483],[-60.67423,-15.1122],[-60.34999,-14.99707],[-60.63603,-13.84119],[-61.07283,-13.62569],[-61.9025,-13.62647],[-62.21395,-13.25048],[-62.80185,-13.10905],[-63.17194,-12.76568],[-63.74229,-12.54071],[-64.32845,-12.59578],[-65.10261,-12.0682],[-65.45781,-11.27865],[-65.41641,-9.838943],[-66.52331,-9.985873],[-67.66452,-10.80093],[-67.99778,-10.75991],[-68.52286,-11.20807],[-69.88988,-11.02776],[-70.30957,-11.1699],[-70.71896,-11.02003],[-70.68128,-9.669083],[-71.27536,-10.08971],[-72.18053,-10.09967],[-72.41623,-9.587397],[-73.29207,-9.454149],[-73.0625,-9.017267],[-73.61432,-8.40982],[-74.09056,-7.527548],[-74.03652,-7.27885],[-73.84718,-7.238285],[-73.78618,-6.774872],[-73.22362,-6.430106],[-73.33719,-6.029736],[-72.93016,-5.038711],[-71.93973,-4.425027],[-70.96802,-4.248294],[-70.79598,-4.064931],[-70.02393,-4.167345],[-69.51025,-1.134089],[-69.70776,-0.567619],[-70.13645,-0.226161],[-70.14083,0.5844],[-69.26594,0.806502],[-69.34226,0.968924],[-69.92481,1.015705],[-69.92343,1.773851],[-68.38511,1.82943],[-68.24848,2.119808],[-67.94571,1.948424],[-67.37696,2.327468],[-67.05751,1.858336],[-67.00579,1.291603],[-66.79967,1.314684],[-66.28683,0.857709],[-65.67671,1.111146],[-65.42494,0.966549],[-65.15671,1.24203],[-64.27483,1.601591],[-64.0486,2.065137],[-63.47236,2.279358],[-64.13446,2.433909],[-64.10005,2.723778],[-64.32628,3.118275],[-64.28142,3.541983],[-64.88451,4.117671],[-64.88064,4.342461],[-64.13653,4.223152],[-63.95465,4.021316],[-63.17706,4.048301],[-62.96093,3.763658],[-62.82024,4.106019],[-62.49922,4.270815],[-61.91181,4.26284],[-61.35393,4.630097],[-61.04904,4.623115],[-60.70452,4.969851],[-60.78709,5.296764],[-60.22457,5.371207],[-59.89857,5.107541],[-59.97549,4.603025],[-59.59676,4.439875],[-59.41942,3.96994],[-59.71017,3.542008],[-59.88955,2.72301],[-59.63006,2.316332],[-59.63382,1.966581],[-59.18812,1.478079],[-58.80545,1.320732],[-58.35933,1.689932],[-57.6,1.803907],[-57.39854,2.065119],[-57.12392,2.128758],[-56.02925,1.949445],[-56.23884,2.263348],[-55.98195,2.628657],[-55.64816,2.519953],[-54.93958,2.682515],[-54.24988,2.25056],[-53.73937,2.473731],[-52.98578,2.280494],[-52.65712,2.564069],[-52.41739,3.22121],[-51.73983,4.119158],[-51.7246,4.556867],[-51.0112,5.522895],[-43.48209,5.335832],[-29.3325,2.335959]]]},{"id":"Haiti-Drone","name":"Imagerie Drone (Haiti)","type":"tms","template":"http://wms.openstreetmap.fr/tms/1.0.0/iomhaiti/{zoom}/{x}/{y}","polygon":[[[-72.1547401,19.6878969],[-72.162234,19.689011],[-72.164995,19.6932445],[-72.1657838,19.6979977],[-72.161603,19.7035677],[-72.1487449,19.7028993],[-72.1477194,19.7026765],[-72.1485082,19.7001514],[-72.1436963,19.7011169],[-72.1410143,19.7000029],[-72.139476,19.6973664],[-72.1382533,19.6927617],[-72.1386872,19.6923161],[-72.1380561,19.6896423],[-72.1385294,19.6894938],[-72.1388055,19.6901251],[-72.1388844,19.6876741],[-72.1378195,19.6872656],[-72.13778,19.6850003],[-72.1369517,19.6855945],[-72.136794,19.6840719],[-72.135729,19.6835148],[-72.1355713,19.6740817],[-72.1366362,19.6708133],[-72.1487843,19.6710733],[-72.1534779,19.6763843],[-72.1530835,19.6769414],[-72.1533251,19.6769768],[-72.1532807,19.6796525],[-72.1523834,19.6797175],[-72.1522749,19.6803488],[-72.1519101,19.6803395],[-72.1518608,19.6805067],[-72.1528173,19.6806552],[-72.1522299,19.6833011],[-72.1507801,19.6831499],[-72.1504457,19.6847862],[-72.1508591,19.6843492],[-72.1530087,19.6849898],[-72.1546258,19.6854354],[-72.1543103,19.6870694],[-72.1547244,19.6868466],[-72.1548501,19.6877564],[-72.1545814,19.6877982],[-72.1547401,19.6878969]],[[-72.1310601,19.6718929],[-72.1259842,19.6772765],[-72.1255379,19.6776179],[-72.1216891,19.6776442],[-72.1149677,19.672602],[-72.1152745,19.6687152],[-72.1198205,19.6627535],[-72.1227768,19.6625696],[-72.1248965,19.662701],[-72.1285779,19.6645394],[-72.1308091,19.6661677],[-72.1316737,19.668794],[-72.1315621,19.671],[-72.1310601,19.6718929]],[[-71.845795,19.6709758],[-71.8429354,19.6759525],[-71.8410027,19.6759525],[-71.8380249,19.6755254],[-71.8378671,19.6745041],[-71.8390504,19.6743927],[-71.8390109,19.6741141],[-71.8398392,19.673947],[-71.8389123,19.6736127],[-71.8380249,19.67209],[-71.8380052,19.6726285],[-71.8376699,19.6727214],[-71.8376305,19.672545],[-71.8354414,19.6732135],[-71.835333,19.6729999],[-71.8331242,19.6734642],[-71.8326706,19.6716815],[-71.8321579,19.67209],[-71.8307183,19.6694902],[-71.8306009,19.6697594],[-71.8302174,19.6698907],[-71.8291833,19.6672095],[-71.8290749,19.6672095],[-71.8289122,19.6667916],[-71.8289516,19.6666199],[-71.8288333,19.6663506],[-71.8285572,19.6664759],[-71.8288678,19.6672466],[-71.8287593,19.6674138],[-71.8277979,19.6678177],[-71.8277112,19.6678586],[-71.8278263,19.6679637],[-71.8271831,19.6681212],[-71.8271761,19.6680917],[-71.8264405,19.6683921],[-71.8264074,19.6683231],[-71.8261954,19.6684253],[-71.8261806,19.6683556],[-71.8258946,19.6684206],[-71.8258897,19.6686574],[-71.8251551,19.6687549],[-71.8254509,19.6691588],[-71.8229332,19.6695739],[-71.822713,19.6696658],[-71.8227688,19.6697577],[-71.8201751,19.6709855],[-71.8198474,19.6704537],[-71.8197985,19.6706014],[-71.8194674,19.6707557],[-71.8182472,19.6713433],[-71.8181426,19.6711431],[-71.8175813,19.6714254],[-71.816959,19.6707672],[-71.8176388,19.6718965],[-71.8171403,19.6720376],[-71.8158225,19.6718045],[-71.8138354,19.6711874],[-71.8123259,19.6706982],[-71.8121759,19.6704258],[-71.8124304,19.6701467],[-71.8119184,19.6700141],[-71.8118765,19.6705828],[-71.811169,19.6703483],[-71.8095938,19.6698516],[-71.8077992,19.6692829],[-71.8056028,19.668612],[-71.8051443,19.6668942],[-71.8051196,19.6652322],[-71.8052315,19.661979],[-71.8065603,19.6523921],[-71.8073412,19.6482946],[-71.8099686,19.6468292],[-71.8147517,19.6454502],[-71.8147726,19.6455619],[-71.8150027,19.6455093],[-71.8149469,19.6453846],[-71.8159928,19.6450234],[-71.8158882,19.6448855],[-71.8165854,19.6446097],[-71.8190119,19.643802],[-71.8211524,19.643454],[-71.8221564,19.6433292],[-71.8269046,19.643211],[-71.8280481,19.6432241],[-71.8304466,19.6440778],[-71.8306419,19.6448592],[-71.8295263,19.6450365],[-71.8296064,19.6456111],[-71.8299411,19.6455651],[-71.8303699,19.6451744],[-71.830471,19.6453452],[-71.8308092,19.6451974],[-71.8310184,19.6451088],[-71.8312519,19.6458541],[-71.8311125,19.6458245],[-71.831367,19.6465862],[-71.8328939,19.646189],[-71.8344566,19.6457062],[-71.8344664,19.6463052],[-71.834215,19.6461938],[-71.8342002,19.6465513],[-71.8346702,19.6463],[-71.8349118,19.6463905],[-71.8347984,19.6462187],[-71.8354393,19.6458496],[-71.8355034,19.6458032],[-71.8364747,19.6461328],[-71.8376382,19.6472658],[-71.8379143,19.647888],[-71.8390483,19.6508039],[-71.8456942,19.6696203],[-71.845795,19.6709758]],[[-72.098878,18.54843],[-72.096993,18.5501994],[-72.0972888,18.5503209],[-72.0968451,18.5503489],[-72.0955632,18.551854],[-72.0956428,18.5526742],[-72.0959914,18.5533748],[-72.0962145,18.553203],[-72.0962842,18.5535665],[-72.0964446,18.5535533],[-72.0965352,18.5539764],[-72.0965056,18.554173],[-72.0966085,18.5541747],[-72.0965178,18.5542127],[-72.0968769,18.5546588],[-72.0979018,18.5552141],[-72.1006211,18.5555875],[-72.1014926,18.5556206],[-72.1024339,18.5555016],[-72.103417,18.5543515],[-72.1034798,18.5516215],[-72.1030789,18.5516149],[-72.1033752,18.5515224],[-72.1035042,18.5515224],[-72.1035239,18.5502417],[-72.1028701,18.5503062],[-72.1029015,18.55025],[-72.1028457,18.5501773],[-72.1035081,18.5500252],[-72.103491,18.5497396],[-72.1035181,18.5497361],[-72.1035398,18.5489039],[-72.1034317,18.5487056],[-72.102717,18.5481437],[-72.1025601,18.5481536],[-72.10229,18.5482751],[-72.1022891,18.5482569],[-72.1025201,18.5481396],[-72.1023388,18.5481321],[-72.0999082,18.5480901],[-72.09907,18.5483799],[-72.098878,18.54843]],[[-72.2542503,18.568262],[-72.2560252,18.5717765],[-72.2557886,18.5748049],[-72.2535009,18.5755526],[-72.2522782,18.5755526],[-72.2499906,18.5740945],[-72.2473874,18.5698323],[-72.2460069,18.566729],[-72.2458492,18.5629527],[-72.2479396,18.5625414],[-72.2501483,18.5628031],[-72.2519232,18.5650839],[-72.2542503,18.568262]],[[-72.303145,18.5332749],[-72.3031275,18.5331799],[-72.3048311,18.5311081],[-72.3097397,18.5311081],[-72.3164332,18.5324302],[-72.3234056,18.5366083],[-72.3261388,18.5387765],[-72.3261946,18.5426371],[-72.3170468,18.5540596],[-72.3130864,18.5540596],[-72.2987511,18.5453342],[-72.2988627,18.5407333],[-72.2962969,18.5404689],[-72.2954602,18.5395169],[-72.2961853,18.5338582],[-72.2971893,18.5332235],[-72.3007034,18.5332764],[-72.3022652,18.5342284],[-72.3028486,18.5335189],[-72.303104,18.5333361],[-72.303181,18.5334007],[-72.3035793,18.5335614],[-72.3030793,18.5346463],[-72.303715,18.5339873],[-72.3045286,18.5344052],[-72.3044015,18.5345097],[-72.3062747,18.5352571],[-72.3063107,18.5352741],[-72.3061219,18.5357628],[-72.3061219,18.5358196],[-72.30637,18.5358928],[-72.3062726,18.5354869],[-72.3066688,18.5350891],[-72.3061963,18.5349706],[-72.3058869,18.5349385],[-72.3055373,18.5346833],[-72.3054864,18.534613],[-72.3055585,18.5345065],[-72.3046749,18.5342293],[-72.3047617,18.5338817],[-72.3043252,18.5337511],[-72.3042595,18.5336346],[-72.303145,18.5332749]],[[-72.2981405,18.477502],[-72.2935652,18.4948587],[-72.2922242,18.4964297],[-72.2931708,18.4972526],[-72.2892266,18.5057058],[-72.2878067,18.5080996],[-72.2850458,18.5119893],[-72.2840203,18.5113161],[-72.2808649,18.515879],[-72.2773151,18.5175994],[-72.2723454,18.5175246],[-72.2662714,18.5144578],[-72.2665869,18.5066783],[-72.2692643,18.5046154],[-72.2661965,18.5029756],[-72.2688181,18.4965222],[-72.2691528,18.4959403],[-72.2702684,18.4961519],[-72.2702684,18.4955964],[-72.2690691,18.49557],[-72.2692922,18.4937714],[-72.2736988,18.4859951],[-72.2746749,18.4850429],[-72.2751769,18.483403],[-72.2765435,18.4813398],[-72.2773523,18.4814985],[-72.2783006,18.4809694],[-72.2778544,18.4807049],[-72.2771013,18.480123],[-72.2789978,18.4775836],[-72.279723,18.4772927],[-72.2806433,18.4776365],[-72.2813685,18.4771604],[-72.2808386,18.4769752],[-72.2812848,18.4758378],[-72.2823167,18.4751765],[-72.2851615,18.4750971],[-72.2849941,18.4763668],[-72.2854404,18.4769752],[-72.286277,18.4756262],[-72.2869325,18.4754675],[-72.2865978,18.4751897],[-72.2865978,18.4750046],[-72.2909765,18.4747268],[-72.2946579,18.4749384],[-72.2973911,18.476843],[-72.2981405,18.477502]],[[-72.3466657,18.5222375],[-72.346833,18.5244325],[-72.3475303,18.5277645],[-72.3455501,18.5291131],[-72.3403069,18.5292189],[-72.3383267,18.5280289],[-72.3369043,18.530118],[-72.3338086,18.5296684],[-72.3289279,18.5270769],[-72.328649,18.5253316],[-72.3292068,18.5232689],[-72.330406,18.5220524],[-72.3321631,18.5221847],[-72.3322467,18.5191963],[-72.3369183,18.5183633],[-72.3382012,18.5184691],[-72.3381454,18.5181782],[-72.3411993,18.5177947],[-72.3454943,18.5171997],[-72.3492595,18.517279],[-72.3504308,18.5188922],[-72.3503472,18.5206112],[-72.3496778,18.5220392],[-72.3466657,18.5222375]],[[-72.3303078,18.5486462],[-72.3429687,18.5508149],[-72.3433236,18.5530585],[-72.3413121,18.5614341],[-72.3390639,18.5613593],[-72.3384723,18.5638271],[-72.3375257,18.5654348],[-72.3348436,18.5650609],[-72.3311755,18.5638271],[-72.3312149,18.5616211],[-72.3232082,18.5606863],[-72.3212361,18.559602],[-72.3208023,18.5587046],[-72.3208811,18.557882],[-72.3259493,18.5580274],[-72.3266186,18.5581993],[-72.3259214,18.5577498],[-72.3250986,18.5573797],[-72.3233767,18.552263],[-72.3245994,18.5478507],[-72.3288986,18.5483742],[-72.329979,18.5489548],[-72.3303078,18.5486462]],[[-72.3231383,18.5269828],[-72.3223434,18.528067],[-72.3209629,18.5279745],[-72.3207816,18.5271282],[-72.3208513,18.5253697],[-72.3214649,18.5249598],[-72.3225666,18.5248937],[-72.3228454,18.52533],[-72.3232359,18.5264804],[-72.3231383,18.5269828]],[[-72.2160832,18.6457752],[-72.2159649,18.6553795],[-72.2030279,18.6558279],[-72.1947057,18.6553421],[-72.1922208,18.6545573],[-72.1920631,18.6521283],[-72.193483,18.6477559],[-72.201253,18.6385249],[-72.2069327,18.6388239],[-72.2120996,18.6424117],[-72.2118068,18.6430591],[-72.2121693,18.6426892],[-72.2127968,18.6427552],[-72.2134662,18.6431252],[-72.2135638,18.6437462],[-72.2154176,18.6443947],[-72.2158909,18.6450301],[-72.2160832,18.6457752]],[[-72.2867654,18.6482017],[-72.2900977,18.6527446],[-72.28981,18.6536532],[-72.2900738,18.6542664],[-72.290721,18.6537667],[-72.2910327,18.6544709],[-72.2912485,18.654221],[-72.29168,18.6558905],[-72.2912245,18.656606],[-72.2922673,18.65597],[-72.2926869,18.6567536],[-72.2930705,18.6567309],[-72.2941253,18.6581846],[-72.2960192,18.6608421],[-72.2959713,18.6619096],[-72.2932862,18.664567],[-72.2906731,18.6659979],[-72.2895943,18.6661342],[-72.2895943,18.6665657],[-72.2877004,18.6664749],[-72.2875805,18.6676559],[-72.2831214,18.6697227],[-72.2796453,18.6696546],[-72.2784311,18.6690787],[-72.2783972,18.6687736],[-72.277736,18.6691671],[-72.2774394,18.669143],[-72.2770071,18.6683159],[-72.2765575,18.6681125],[-72.2765385,18.6680583],[-72.2752319,18.6685239],[-72.2749292,18.6674649],[-72.2746416,18.6674309],[-72.2734668,18.6682145],[-72.2732271,18.6682712],[-72.2726757,18.6671583],[-72.2719147,18.6674288],[-72.2718808,18.6673405],[-72.2688149,18.6681868],[-72.2688269,18.6671761],[-72.2690786,18.6668241],[-72.2688149,18.66679],[-72.2681077,18.6670739],[-72.2676282,18.6673805],[-72.2675563,18.6666878],[-72.266861,18.666949],[-72.2655904,18.6673578],[-72.2654466,18.6670058],[-72.2647514,18.6674146],[-72.2629893,18.6681868],[-72.2628455,18.6681754],[-72.2626537,18.6676076],[-72.2623001,18.6677098],[-72.2624799,18.6679199],[-72.2624799,18.6682322],[-72.262306,18.6682606],[-72.2620963,18.6679654],[-72.2622761,18.6689193],[-72.2601484,18.6688966],[-72.2542749,18.6687944],[-72.2505388,18.6683476],[-72.2504371,18.669536],[-72.2477926,18.6698893],[-72.2415204,18.669793],[-72.2414187,18.6741933],[-72.2389167,18.6739759],[-72.2387249,18.6734649],[-72.2383653,18.6733059],[-72.2387009,18.6739532],[-72.2375502,18.6738964],[-72.2374183,18.6735103],[-72.237742,18.67334],[-72.2375142,18.6732605],[-72.236843,18.6734876],[-72.2364354,18.6724088],[-72.2355124,18.6726019],[-72.2354045,18.6724202],[-72.2353027,18.6729028],[-72.2345475,18.6726871],[-72.2343077,18.6724599],[-72.2342358,18.6734706],[-72.2334087,18.6734592],[-72.2332889,18.6733003],[-72.2327375,18.6732889],[-72.2327135,18.6735047],[-72.227703,18.6725281],[-72.2265283,18.6716537],[-72.226804,18.6715742],[-72.2274993,18.6715855],[-72.2274873,18.6714493],[-72.2272899,18.6714623],[-72.2272814,18.6712977],[-72.2272094,18.671358],[-72.2261785,18.6713693],[-72.2256032,18.670881],[-72.2255073,18.6694502],[-72.2261066,18.6696886],[-72.2261785,18.6695949],[-72.2259837,18.6695495],[-72.225777,18.6691379],[-72.2253335,18.6694643],[-72.2249739,18.66947],[-72.2245783,18.6678802],[-72.2235525,18.6677046],[-72.2235907,18.6675921],[-72.2224634,18.6676283],[-72.2223659,18.667022],[-72.2223277,18.6670943],[-72.2219209,18.667026],[-72.2208105,18.6669015],[-72.220809,18.6665325],[-72.2208705,18.6663593],[-72.2206023,18.6668107],[-72.2203895,18.6666361],[-72.2184341,18.6650535],[-72.21829,18.6640979],[-72.2183493,18.6608376],[-72.2187223,18.6606541],[-72.2186894,18.660603],[-72.2187253,18.6604525],[-72.2189771,18.6603247],[-72.2187823,18.6601998],[-72.2186984,18.6602367],[-72.2185815,18.6600352],[-72.2186085,18.6600039],[-72.2187823,18.6601345],[-72.218995,18.6600181],[-72.2189111,18.6599131],[-72.2189681,18.6597938],[-72.2183807,18.6595837],[-72.2184728,18.6539662],[-72.2201001,18.6511554],[-72.225796,18.6469472],[-72.2283048,18.6457265],[-72.2379335,18.645855],[-72.237764,18.6446985],[-72.2400355,18.6432529],[-72.2455958,18.6433493],[-72.2482742,18.6450358],[-72.2487488,18.6436705],[-72.2511067,18.6429775],[-72.2512385,18.6433409],[-72.2512625,18.6431592],[-72.2514843,18.6431365],[-72.2513284,18.6429718],[-72.2533602,18.6423471],[-72.253516,18.6426765],[-72.2539535,18.6425402],[-72.2541453,18.642932],[-72.2543851,18.6428696],[-72.2543791,18.6427503],[-72.2564168,18.6423244],[-72.2566925,18.6431365],[-72.2568783,18.6428582],[-72.2568184,18.6425288],[-72.258843,18.6420991],[-72.258885,18.6422467],[-72.2592626,18.6422297],[-72.2596461,18.6424057],[-72.2592206,18.6406907],[-72.2599545,18.6404815],[-72.2601156,18.6406341],[-72.2601156,18.6399393],[-72.2615268,18.6394669],[-72.2626056,18.6391034],[-72.2654465,18.6387286],[-72.2719433,18.6386832],[-72.272201,18.6388649],[-72.2730341,18.6394158],[-72.273166,18.6412558],[-72.2738732,18.6410286],[-72.2742208,18.6416079],[-72.2752187,18.6416987],[-72.2754524,18.6415738],[-72.2755513,18.6416874],[-72.2755394,18.6417527],[-72.2764713,18.6418634],[-72.276753,18.6418975],[-72.2762953,18.6426002],[-72.2774226,18.6429978],[-72.277982,18.6427247],[-72.2785796,18.6431303],[-72.2785669,18.6432307],[-72.2789017,18.6433471],[-72.279851,18.6439655],[-72.2858703,18.6469651],[-72.2867654,18.6482017]],[[-72.5557247,18.5305893],[-72.5555866,18.5367036],[-72.554995,18.537975],[-72.5488026,18.537919],[-72.5486646,18.5372832],[-72.548842,18.5306267],[-72.5493745,18.5301031],[-72.555133,18.5301218],[-72.5557247,18.5305893]],[[-72.6235278,18.5079877],[-72.6234441,18.5095217],[-72.6226074,18.5104341],[-72.6204878,18.511849],[-72.6183403,18.5107514],[-72.6162207,18.5083183],[-72.6162625,18.506467],[-72.618661,18.5044438],[-72.6204041,18.5044967],[-72.6228305,18.506996],[-72.6235278,18.5079877]]]},{"id":"osmim-imagicode-LC80700162014211LGN00","name":"imagico.de OSM images for mapping: Alaska Range","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC80700162014211LGN00&z={zoom}&x={x}&y={-y}","description":"LC80700162014211LGN00, 2014-07-31 channels 234 (true color), Recent summer image of the Alaska Range for mapping natural features","scaleExtent":[0,12],"polygon":[[[-152.708729431479,62.3036424122946],[-152.708729431479,63.5464553885127],[-148.994366411548,63.5464553885127],[-148.994366411548,62.3036424122946],[-152.708729431479,62.3036424122946]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81190582014075LGN00","name":"imagico.de OSM images for mapping: Bakun Reservoir","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81190582014075LGN00&z={zoom}&x={x}&y={-y}","description":"LC81190582014075LGN00/LC81180582015183LGN00, 2014-03-16, channels 234 (true color), Missing in older pre-2011 images","scaleExtent":[0,13],"polygon":[[[113.53447549873,2.02707458823865],[113.53447549873,3.07076712442006],[114.765167437974,3.07076712442006],[114.765167437974,2.02707458823865],[113.53447549873,2.02707458823865]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81250592016107LGN00","name":"imagico.de OSM images for mapping: Batam","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81250592016107LGN00&z={zoom}&x={x}&y={-y}","description":"LC81250592016107LGN00, LC81250602015184LGN00, LC81240602014174LGN00, 2014-2016, channels 234 (true color), Missing Islands in OSM","scaleExtent":[0,13],"polygon":[[[104.001374040597,0],[104.001374040597,1.45116299803241],[104.910109782012,1.45116299803241],[104.910109782012,0],[104.001374040597,0]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81800982013291LGN00","name":"imagico.de OSM images for mapping: Bouvet Island","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81800982013291LGN00&z={zoom}&x={x}&y={-y}","description":"LC81800982013291LGN00, 2013-10-18, channels 234 (true color), For more accurate coastline and glacier mapping","scaleExtent":[0,13],"polygon":[[[3.24652940311363,-54.4705168479877],[3.24652940311363,-54.3753916879791],[3.46391271871771,-54.3753916879791],[3.46391271871771,-54.4705168479877],[3.24652940311363,-54.4705168479877]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","best":true},{"id":"osmim-imagicode-LC82050982015344LGN00","name":"imagico.de OSM images for mapping: Clerke Rocks","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC82050982015344LGN00&z={zoom}&x={x}&y={-y}","description":"LC82050982015344LGN00, 2015-12-10, channels 234 (true color), Missing in other image sources","scaleExtent":[0,13],"polygon":[[[-35.1959928318028,-55.2968852515402],[-35.1959928318028,-54.7209735214882],[-34.1252010131324,-54.7209735214882],[-34.1252010131324,-55.2968852515402],[-35.1959928318028,-55.2968852515402]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-S2A_R022_N06_20151221T103009","name":"imagico.de OSM images for mapping: Cotonou","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R022_N06_20151221T103009&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20151222T164644_R022_V20151221T103009_20151221T103009, 2015-12-21, channels 234 (true color), Patchy and partly cloudy coverage in usual sources","scaleExtent":[0,14],"polygon":[[[1.83974970187678,6.25776229826032],[1.83974970187678,7.1142717924319],[2.5494187763312,7.1142717924319],[2.5494187763312,6.25776229826032],[1.83974970187678,6.25776229826032]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC80360072014245LGN00","name":"imagico.de OSM images for mapping: Eastern Devon Island coast","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC80360072014245LGN00&z={zoom}&x={x}&y={-y}","description":"LC80360072014245LGN00/LC80380062014243LGN00, 2014-09-02, channel 654 (false color IR), Coastline mostly mapped meanwhile","scaleExtent":[0,11],"polygon":[[[-84.3479873388655,74.3894989734754],[-84.3479873388655,75.8903032392084],[-79.1485833901459,75.8903032392084],[-79.1485833901459,74.3894989734754],[-84.3479873388655,74.3894989734754]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC82160152013239LGN00","name":"imagico.de OSM images for mapping: Eastern Iceland","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC82160152013239LGN00&z={zoom}&x={x}&y={-y}","description":"LC82160152013239LGN00, 2013-08-27, channels 234 (true color), Missing islets and inaccurate coast","scaleExtent":[0,12],"polygon":[[[-15.1680535723581,64.2088554380107],[-15.1680535723581,64.8157280042209],[-13.0435379254154,64.8157280042209],[-13.0435379254154,64.2088554380107],[-15.1680535723581,64.2088554380107]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-AST_L1T_00302052007154424_20150518041444_91492","name":"imagico.de OSM images for mapping: El Altar","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=AST_L1T_00302052007154424_20150518041444_91492&z={zoom}&x={x}&y={-y}","description":"AST_L1T_00302052007154424_20150518041444_91492, 2012-02-05, channels 12x (true color with estimated blue), 2007 ASTER image offering better glacier coverage than common sources","scaleExtent":[0,14],"polygon":[[[-78.531997745432,-1.8050814821624],[-78.531997745432,-1.60810556500124],[-78.3355811085593,-1.60810556500124],[-78.3355811085593,-1.8050814821624],[-78.531997745432,-1.8050814821624]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-S2A_R009_S61_20160109","name":"imagico.de OSM images for mapping: Elephant Island/Clarence Island","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R009_S61_20160109&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20160109T225906_R009_V20160109T130043_20160109T130043, 2016-01-09, channels 234 (true color), Fairly clear up-to-date image for updating glacier edges","scaleExtent":[0,13],"polygon":[[[-56.1347609072749,-61.634696838288],[-56.1347609072749,-60.8398161307814],[-53.723458105877,-60.8398161307814],[-53.723458105877,-61.634696838288],[-56.1347609072749,-61.634696838288]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC82100502015347LGN00","name":"imagico.de OSM images for mapping: Fogo, Cape Verde","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC82100502015347LGN00&z={zoom}&x={x}&y={-y}","description":"LC82100502015347LGN00, 2015-12-13, channels 234 (true color), Image from after the 2014/2015 eruption","scaleExtent":[0,14],"polygon":[[[-24.7587819559676,14.7481298855965],[-24.7587819559676,15.0924935449651],[-24.2670621357462,15.0924935449651],[-24.2670621357462,14.7481298855965],[-24.7587819559676,14.7481298855965]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-greenland","name":"imagico.de OSM images for mapping: Greenland mosaic","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=greenland&z={zoom}&x={x}&y={-y}","description":"mostly Landsat 8 2013-2015 channels 234 (true color), Landsat mosaic of Greenland","scaleExtent":[0,12],"polygon":[[[-43.335169388775576,59.78884556778711],[-43.5940638938192,59.723921705576714],[-43.840898275878764,59.67490148496335],[-44.23515133460447,59.653417915878954],[-44.657213255061194,59.680989005977885],[-45.81015180316172,59.81951972989828],[-46.81057076187592,59.98139710469466],[-47.20837894817284,60.150960472742064],[-47.22064190066637,60.33805731472787],[-47.255916208498,60.42332684576548],[-47.34990349056956,60.446387835215525],[-47.51603887007207,60.45119769375011],[-47.65139646003081,60.48896403744677],[-47.79170835578903,60.52050863908786],[-49.10695022655055,60.73414367492607],[-49.52399924941209,60.97440124547532],[-50.493558334841985,61.089523147855694],[-51.1011476720755,61.3931538528416],[-51.226493283028084,61.8368218735183],[-51.66491000695862,62.06066494936552],[-51.98744899262875,62.355028063412306],[-52.04791761614332,62.676138274608135],[-52.68385390751712,62.89777335327022],[-53.00141158114564,63.22960936121321],[-52.98804591383922,63.665519960839994],[-53.37455124039754,63.88257990608798],[-53.462018437442744,64.21700667649995],[-53.625006563694996,64.39608940752123],[-53.62418230433685,64.87666336480167],[-53.92737410039694,65.14174166474336],[-54.58568916434171,65.51879633173807],[-55.020580045260964,66.04786962007503],[-54.974959716968506,66.43747058777413],[-55.04621700056885,66.81068389526814],[-55.18883177742317,67.07445292724583],[-55.295917291513724,67.2980754937805],[-55.49386806070968,67.62765205772878],[-55.58982586875712,67.74762927352513],[-55.800191618857184,68.05623485476666],[-56.166042896634444,68.44155152338232],[-56.086954623441976,68.68479069915158],[-55.692397350070934,69.09499941753234],[-55.78268862269791,69.35591450732602],[-55.97508469715559,69.51460160299163],[-56.22131441053026,69.61961934478276],[-56.28674985487528,69.75311038137812],[-56.27734150260429,69.86115681621736],[-56.47867255356253,69.98628865160101],[-56.729667549723445,70.20797294037203],[-56.780049018329095,70.4030123058809],[-56.66995480486827,70.53429026926025],[-56.76965573535976,70.59936425752305],[-56.750047814068225,70.67605894741244],[-56.630475021762926,70.75228057874938],[-56.63957096755714,70.79345598378389],[-56.95453022049966,70.92185386457368],[-57.682941688207656,71.10356260725686],[-57.9990573064922,71.18275256548473],[-58.06673093129251,71.31878823942327],[-57.73776694812512,71.73468567987527],[-57.688607830732714,71.96425305773354],[-57.29627634430133,72.25939767922573],[-57.027097307050845,72.49722993388094],[-57.22262816078322,72.61296218481311],[-57.61910829550675,72.72652221937263],[-58.05813139640902,73.01331566875426],[-58.76645057271363,73.2808359719379],[-59.14761885260487,73.53482225342569],[-59.03651118375505,73.80651043385626],[-58.8823279108656,74.19210040380365],[-59.24788269229215,74.4273495816669],[-59.99510425025614,74.65678100854564],[-60.806460490534164,74.7868931828055],[-61.54936387752781,74.99717139513008],[-62.44046860998914,75.00073689358435],[-62.985115364477565,75.11722591645595],[-63.51928606785155,75.31691397958907],[-63.64288486720879,75.52488932122031],[-64.1242392273263,75.5921799154749],[-64.58761243996756,75.53593567213079],[-65.31057987327657,75.42103306523184],[-65.99461388511591,75.4041967649632],[-66.28964875049822,75.41792163747078],[-68.76453492310549,75.13410011250316],[-71.04622564987365,74.79937286637706],[-73.5067977908339,75.97399646374085],[-74.5601685819203,76.43273848659732],[-74.5601685819203,82.6959322619224],[-12.86174239943403,82.6959322619224],[-11.878165975221727,82.54102593940235],[-10.7797834094343,82.51187042401891],[-10.7797834094343,78.34458993192563],[-10.838211677734567,78.32665786610472],[-12.549216515959552,77.9578508228317],[-12.803493182847879,77.85845362808246],[-12.916087338718654,77.65848905807152],[-13.070950321133406,77.52877948776312],[-13.47955419255021,77.40221679143431],[-14.13060832134256,77.30552053875587],[-14.69541342101231,77.14674387861214],[-14.882617750618206,76.84736003108713],[-14.323648701941867,76.53205658256601],[-12.810144796765599,76.24823964501138],[-12.151831546734856,75.86267532270129],[-12.987745033472448,75.38717284756257],[-14.066766809859267,74.8451997920592],[-15.423357647282502,74.4551642069618],[-17.28174157007599,74.24584688808936],[-19.113380020736102,73.72978765991853],[-20.062373344103577,73.11108267968514],[-20.162312506727517,72.6186060300425],[-19.85354831628143,72.0718529721276],[-19.943252248300748,71.55019790921727],[-20.918542646451737,70.67423312425346],[-21.379621573201593,70.27938590726379],[-21.725469254364587,70.05299977015657],[-21.93869730345768,69.92215619574657],[-22.463306498894173,69.6235894257334],[-23.059252433112615,69.5491649852365],[-23.860796144964162,69.34443527043162],[-24.74741743781591,68.93340370554307],[-25.481987646795183,68.76711754662492],[-25.815395630476477,68.51279831615729],[-26.344103298317982,68.32443780018751],[-27.449680541202035,68.19315579455328],[-28.42826258633533,67.66140945836786],[-29.237141834543507,67.60310787132272],[-30.062476147434136,67.41414423917192],[-31.96817868027385,66.21262359095492],[-33.33718066100074,65.93894291103432],[-33.86781919039464,65.7415652217968],[-34.94415141573626,65.29121928843726],[-36.438872573697054,65.22802281646563],[-36.716767002697864,65.14683055370199],[-36.97927615837815,64.90967633661491],[-37.473922616631825,64.38546237809376],[-38.95785728548117,62.7419538908273],[-39.61555442323402,61.96904156671025],[-40.549088272349444,60.92614046823071],[-41.17137829347243,60.43812852329213],[-42.07544989793619,60.311876129737485],[-42.734129957211564,60.001556976048406],[-43.335169388775576,59.78884556778711]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-S2A_R047_S54_20160411T044330","name":"imagico.de OSM images for mapping: Heard Island coast","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R047_S54_20160411T044330&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20160412T212111_R047_V20160411T044330_20160411T044330, 2016-04-12, channels 234 (true color), Recent image of Heard island with interior mostly cloud covered but mostly well visible coast","scaleExtent":[0,13],"polygon":[[[73.0689652102818,-53.2705500548086],[73.0689652102818,-52.8754896362687],[74.0885530577575,-52.8754896362687],[74.0885530577575,-53.2705500548086],[73.0689652102818,-53.2705500548086]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC82280982013259LGN00","name":"imagico.de OSM images for mapping: Isla Londonderry","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC82280982013259LGN00&z={zoom}&x={x}&y={-y}","description":"LC82280982013259LGN00, 2013-09-16, channel 654 (false color IR), A lot of very coarse coastlines could be improved here, much snow cover though so no use for glacier mapping","scaleExtent":[0,12],"polygon":[[[-72.2652065929688,-55.5594608405404],[-72.2652065929688,-54.178890106312],[-69.4910293325508,-54.178890106312],[-69.4910293325508,-55.5594608405404],[-72.2652065929688,-55.5594608405404]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-AST_L1T_00311162013112731_20150618142416_109190","name":"imagico.de OSM images for mapping: Leskov Island ASTER","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=AST_L1T_00311162013112731_20150618142416_109190&z={zoom}&x={x}&y={-y}","description":"AST_L1T_00311162013112731_20150618142416_109190, 2013-11-16, channels 12x (true color with estimated blue), Missing in other image sources","scaleExtent":[0,13],"polygon":[[[-28.2107470814065,-56.721108415345],[-28.2107470814065,-56.6249750430891],[-27.9696123096903,-56.6249750430891],[-27.9696123096903,-56.721108415345],[-28.2107470814065,-56.721108415345]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81991002015286LGN00","name":"imagico.de OSM images for mapping: Leskov Island Landsat","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81991002015286LGN00&z={zoom}&x={x}&y={-y}","description":"LC81991002015286LGN00, 2015-10-13, channels 234 (true color), Missing in other image sources","scaleExtent":[0,13],"polygon":[[[-28.2277611728877,-56.7347696464053],[-28.2277611728877,-56.6007525373185],[-27.9690463710613,-56.6007525373185],[-27.9690463710613,-56.7347696464053],[-28.2277611728877,-56.7347696464053]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-ls_polar","name":"imagico.de OSM images for mapping: May 2013 off-nadir Landsat","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=ls_polar&z={zoom}&x={x}&y={-y}","description":"LC80372442013137LGN01-LC80530012013137LGN01, 2013-05-17, channels 234 (true color), Only available image north of the regular Landsat limit, mostly with seasonal snow cover so difficult to interpret","scaleExtent":[0,10],"polygon":[[[-89.8315284119521,81.3934028410464],[-89.8315284119521,83.7045077508689],[-17.9663056823904,83.7045077508689],[-17.9663056823904,81.3934028410464],[-89.8315284119521,81.3934028410464]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC80940622015159LGN00","name":"imagico.de OSM images for mapping: New Ireland","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC80940622015159LGN00&z={zoom}&x={x}&y={-y}","description":"LC80940622015159LGN00, 2015-06-08, channels 234 (true color), Many missing islands in OSM (mostly mapped meanwhile)","scaleExtent":[0,14],"polygon":[[[150.388533766196,-2.80056783608088],[150.388533766196,-2.38339617820643],[150.833478309574,-2.38339617820643],[150.833478309574,-2.80056783608088],[150.388533766196,-2.80056783608088]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-nellesmere_ast","name":"imagico.de OSM images for mapping: Northern Ellesmere Island","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=nellesmere_ast&z={zoom}&x={x}&y={-y}","description":"ASTER L1T, 2012-07-09/2012-07-15, channels 12x (true color with estimated blue), Assembled from July 2012 ASTER imagery","scaleExtent":[0,10],"polygon":[[[-83.0313625595429,82.4597689567848],[-83.0313625595429,83.0958397705009],[-65.6583851391606,83.0958397705009],[-65.6583851391606,82.4597689567848],[-83.0313625595429,82.4597689567848]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81960222015233LGN00vis","name":"imagico.de OSM images for mapping: Northern German west coast tidalflats","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81960222015233LGN00vis&z={zoom}&x={x}&y={-y}","description":"LC81960222015233LGN00, 2015-08-21 channels 134 (true color), Up-to-date low tide imagery of the coast for updating mapping of tidalflats and shoals","scaleExtent":[0,12],"polygon":[[[7.63567991501593,53.2802190281286],[7.63567991501593,55.502457780526],[9.20773166222509,55.502457780526],[9.20773166222509,53.2802190281286],[7.63567991501593,53.2802190281286]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81960222015233LGN00ir","name":"imagico.de OSM images for mapping: Northern German west coast tidalflats (infrared)","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81960222015233LGN00ir&z={zoom}&x={x}&y={-y}","description":"LC81960222015233LGN00, 2015-08-21 channel 654 (false color IR), Up-to-date low tide imagery of the coast for updating mapping of tidalflats and shoals","scaleExtent":[0,12],"polygon":[[[7.63567991501593,53.2802190281286],[7.63567991501593,55.502457780526],[9.20773166222509,55.502457780526],[9.20773166222509,53.2802190281286],[7.63567991501593,53.2802190281286]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-ngreenland_ast","name":"imagico.de OSM images for mapping: Northern Greenland ASTER","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=ngreenland_ast&z={zoom}&x={x}&y={-y}","description":"ASTER L1T, 2005-06-21 to 2012-08-13, channels 12x (true color with estimated blue), Assembled from mostly 2012 ASTER imagery, some 2005 images mainly in the northeast","scaleExtent":[0,10],"polygon":[[[-52.49221819431,82.4897991404581],[-52.49221819431,83.7321400994933],[-21.1842327268577,83.7321400994933],[-21.1842327268577,82.4897991404581],[-52.49221819431,82.4897991404581]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-EO1A1350972013086110KF","name":"imagico.de OSM images for mapping: Northwest Heard Island","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=EO1A1350972013086110KF&z={zoom}&x={x}&y={-y}","description":"EO1A1350972013086110KF, 2013-03-13, channels 973 (false color IR), Glaciers of Northwest Heard Island (mapped meanwhile)","scaleExtent":[0,13],"polygon":[[[73.2279041335011,-53.2033655831056],[73.2279041335011,-52.9494391381048],[73.7898811920934,-52.9494391381048],[73.7898811920934,-53.2033655831056],[73.2279041335011,-53.2033655831056]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-S2A_R111_N09_20160604T154554","name":"imagico.de OSM images for mapping: Panama Canal","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R111_N09_20160604T154554&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20160607T121312_R111_V20160604T154554_20160604T154554, 2016-06-07, channels 234 (true color), Images of the new locks (but partly cloudy)","scaleExtent":[0,14],"polygon":[[[-80.0165356176622,8.84894832639322],[-80.0165356176622,9.41480707574399],[-79.4685632943493,9.41480707574399],[-79.4685632943493,8.84894832639322],[-80.0165356176622,8.84894832639322]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81511242016033LGN00","name":"imagico.de OSM images for mapping: Pensacola Mountains","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81511242016033LGN00&z={zoom}&x={x}&y={-y}","description":"LC81511242016033LGN00/LC81511232016033LGN00, 2016-02-02, channels 234 (true color), Outside regular Landsat coverage and therefore not in LIMA and Bing/Mapbox","scaleExtent":[0,10],"polygon":[[[-60.6153778814062,-84.1252820431153],[-60.6153778814062,-82.299687854391],[-44.5135525206644,-82.299687854391],[-44.5135525206644,-84.1252820431153],[-60.6153778814062,-84.1252820431153]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-S2A_R136_N41_20150831T093006","name":"imagico.de OSM images for mapping: Prokletije Mountains","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R136_N41_20150831T093006&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20160316T034950_R136_V20150831T093006_20150831T093006, 2015-08-31, channels 234 (true color), Late summer imagery where usual sources are severely limited by clouds and snow","scaleExtent":[0,14],"polygon":[[[19.0842590534772,42.1531616550022],[19.0842590534772,43.0960297809089],[20.6378953373619,43.0960297809089],[20.6378953373619,42.1531616550022],[19.0842590534772,42.1531616550022]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-DMS_1142622_03746_20110415_17533956","name":"imagico.de OSM images for mapping: Qasigiannguit","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=DMS_1142622_03746_20110415_17533956&z={zoom}&x={x}&y={-y}","description":"DMS_1142622_03746_20110415_17533956, 2011-04-15, true color, Icebridge DMS image of the settlement - alignment might be poor","scaleExtent":[0,15],"polygon":[[[-51.2433353705628,68.7997259148871],[-51.2433353705628,68.8530261295114],[-51.140370472697,68.8530261295114],[-51.140370472697,68.7997259148871],[-51.2433353705628,68.7997259148871]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81510432015030LGN00","name":"imagico.de OSM images for mapping: Rann of Kutch","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81510432015030LGN00&z={zoom}&x={x}&y={-y}","description":"various Landsat early 2015, channel 654 (false color IR), Land/water distinction difficult to properly map based on Bing/Mapbox images","scaleExtent":[0,12],"polygon":[[[67.8623118572194,22.3626187997331],[67.8623118572194,24.8869308169273],[71.4900144016907,24.8869308169273],[71.4900144016907,22.3626187997331],[67.8623118572194,22.3626187997331]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-S2A_R093_N41_20150828T092005","name":"imagico.de OSM images for mapping: Rila and Pirin Mountains","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R093_N41_20150828T092005&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20160412T121341_R093_V20150828T092005_20150828T092005, 2015-08-28, channels 234 (true color), Late summer imagery where usual sources are severely limited by clouds and snow","scaleExtent":[0,14],"polygon":[[[22.9923796970391,41.5848941590232],[22.9923796970391,42.2998374736026],[23.9940012388324,42.2998374736026],[23.9940012388324,41.5848941590232],[22.9923796970391,41.5848941590232]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81730602015040LGN00","name":"imagico.de OSM images for mapping: Rwenzori Mountains","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81730602015040LGN00&z={zoom}&x={x}&y={-y}","description":"LC81730602015040LGN00, 2015-02-09, channel 654 (false color IR), Recent image of most of the remaining Rwenzori Mountains glaciers","scaleExtent":[0,13],"polygon":[[[29.7662967768464,0.20687257729646],[29.7662967768464,0.509176367154027],[30.0346684679771,0.509176367154027],[30.0346684679771,0.20687257729646],[29.7662967768464,0.20687257729646]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC80611072014036LGN00","name":"imagico.de OSM images for mapping: Scott Island","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC80611072014036LGN00&z={zoom}&x={x}&y={-y}","description":"LC80611072014036LGN00, 2014-02-05, channels 234 (true color), Missing in other image sources","scaleExtent":[0,13],"polygon":[[[-180,-67.4263452022474],[-180,-67.3252448474477],[-179.824753575046,-67.3252448474477],[-179.824753575046,-67.4263452022474],[-180,-67.4263452022474]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC82100972015347LGN00","name":"imagico.de OSM images for mapping: Shag Rocks","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC82100972015347LGN00&z={zoom}&x={x}&y={-y}","description":"LC82100972015347LGN00, 2015-12-13, channels 234 (true color), Missing in other image sources","scaleExtent":[0,13],"polygon":[[[-42.1462581850356,-53.7205050698923],[-42.1462581850356,-53.4458622334244],[-41.6557780399063,-53.4458622334244],[-41.6557780399063,-53.7205050698923],[-42.1462581850356,-53.7205050698923]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81130622013270LGN00","name":"imagico.de OSM images for mapping: Southeastern Sulawesi","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81130622013270LGN00&z={zoom}&x={x}&y={-y}","description":"LC81130622013270LGN00, 2013-09-27, channels 234 (true color), Missing islands and coarse coastline due to cloud cover in Bing, lakes could also use additional detail","scaleExtent":[0,13],"polygon":[[[120.843824420484,-3.59549835456283],[120.843824420484,-2.51468168634705],[122.626180758858,-2.51468168634705],[122.626180758858,-3.59549835456283],[120.843824420484,-3.59549835456283]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC80281222016035LGN00","name":"imagico.de OSM images for mapping: Southern Transantarctic Mountains","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC80281222016035LGN00&z={zoom}&x={x}&y={-y}","description":"LC80281222016035LGN00/LC80281212016035LGN00, 2016-02-04, channels 234 (true color), Outside regular Landsat coverage and therefore not in LIMA and Bing/Mapbox","scaleExtent":[0,10],"polygon":[[[154.508575968435,-84.5010049969839],[154.508575968435,-82.5848702651189],[177.005570718893,-82.5848702651189],[177.005570718893,-84.5010049969839],[154.508575968435,-84.5010049969839]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-DMS_1142636_160xx_20110507_1822xxxx","name":"imagico.de OSM images for mapping: Thule Air Base","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=DMS_1142636_160xx_20110507_1822xxxx&z={zoom}&x={x}&y={-y}","description":"DMS_1142636_16001_20110507_18221638-DMS_1142636_16076_20110507_18224996, 2011-05-07, true color, Icebridge DMS image - alignment might be poor","scaleExtent":[0,15],"polygon":[[[-68.9397691752981,76.5113260720978],[-68.9397691752981,76.5517569988038],[-68.5074010458985,76.5517569988038],[-68.5074010458985,76.5113260720978],[-68.9397691752981,76.5113260720978]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC80910682014358LGN00","name":"imagico.de OSM images for mapping: Vanatinai","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC80910682014358LGN00&z={zoom}&x={x}&y={-y}","description":"LC80910682014358LGN00, 2014-12-24, channels 234 (true color), Coarse coastline due to cloud cover in Bing/Mapbox","scaleExtent":[0,13],"polygon":[[[153.061381062565,-11.7892410342423],[153.061381062565,-11.0722925205757],[154.411998092239,-11.0722925205757],[154.411998092239,-11.7892410342423],[153.061381062565,-11.7892410342423]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC82330892016031LGN00","name":"imagico.de OSM images for mapping: Volcán Calbuco","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC82330892016031LGN00&z={zoom}&x={x}&y={-y}","description":"LC82330892016031LGN00, 2016-01-31, channels 234 (true color), Image from after the 2015 eruption","scaleExtent":[0,13],"polygon":[[[-72.8669610523419,-41.5174389446875],[-72.8669610523419,-41.045274923011],[-71.8751580966041,-41.045274923011],[-71.8751580966041,-41.5174389446875],[-72.8669610523419,-41.5174389446875]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81490352013282LGN00","name":"imagico.de OSM images for mapping: Western Karakoram","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81490352013282LGN00&z={zoom}&x={x}&y={-y}","description":"LC81490352013282LGN00, 2013-10-09, channels 234 (true color), Represents approximately minimum snow cover so can be well used for glacier mapping","scaleExtent":[0,13],"polygon":[[[73.9309166917002,34.9688073863467],[73.9309166917002,37.0985693236903],[76.5270029470414,37.0985693236903],[76.5270029470414,34.9688073863467],[73.9309166917002,34.9688073863467]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-S2A_R039_S15_20160510T145731","name":"imagico.de OSM images for mapping: Willkanuta Mountains and Quelccaya Ice Cap","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R039_S15_20160510T145731&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20160511T025410_R039_V20160510T145731_20160510T150701, 2016-05-10, channels 234 (true color), Poor and outdated imagery in other sources","scaleExtent":[0,14],"polygon":[[[-71.1807064830626,-14.4978825528812],[-71.1807064830626,-13.7102928800508],[-70.5563773605996,-13.7102928800508],[-70.5563773605996,-14.4978825528812],[-71.1807064830626,-14.4978825528812]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"Interspect_Budapest_2014","name":"Interspect ortofotó 2014","type":"tms","template":"http://geoserver.infobex.hu/Budapest2014/IST/{zoom}/{x}/{y}.jpg","description":"Four districts of Budapest: III, XIII, XIV, XV","scaleExtent":[10,21],"polygon":[[[19.04642,47.61098],[19.05375,47.60995],[19.06033,47.61037],[19.06022,47.61009],[19.06091,47.61023],[19.0755,47.60835],[19.07796,47.60718],[19.07773,47.60627],[19.07599,47.60433],[19.07337,47.59906],[19.07232,47.59332],[19.0723,47.58865],[19.0693,47.5798],[19.06891,47.57742],[19.06949,47.57211],[19.06623,47.56375],[19.06717,47.56427],[19.0692,47.56456],[19.06992,47.56418],[19.07011,47.56363],[19.07785,47.56148],[19.07986,47.56053],[19.08359,47.55604],[19.08516,47.5548],[19.08601,47.5551],[19.08703,47.55488],[19.0984,47.54666],[19.09974,47.54692],[19.10094,47.54656],[19.1015,47.54593],[19.1015,47.54523],[19.10255,47.54458],[19.10939,47.56255],[19.10917,47.56324],[19.11193,47.57058],[19.11235,47.57087],[19.11271,47.57297],[19.11382,47.57379],[19.1144,47.57504],[19.11779,47.58375],[19.11774,47.5844],[19.11844,47.58512],[19.12,47.58924],[19.12008,47.59563],[19.1206,47.59856],[19.12127,47.59952],[19.12266,47.6004],[19.12436,47.6008],[19.1255,47.60048],[19.12577,47.5997],[19.128,47.59885],[19.13058,47.59898],[19.13768,47.60057],[19.13874,47.60043],[19.14144,47.59639],[19.14122,47.59568],[19.14023,47.59527],[19.15557,47.58499],[19.15413,47.58389],[19.15329,47.58013],[19.15344,47.57918],[19.15499,47.57884],[19.16043,47.57871],[19.16043,47.57583],[19.16213,47.57583],[19.16196,47.57383],[19.17573,47.56442],[19.17511,47.56345],[19.16356,47.55986],[19.16295,47.5594],[19.17589,47.55134],[19.18156,47.54896],[19.18205,47.5483],[19.18165,47.54762],[19.16905,47.53994],[19.15316,47.52885],[19.14747,47.52584],[19.14691,47.52332],[19.14947,47.52059],[19.15581,47.51256],[19.1572,47.51155],[19.15697,47.51051],[19.15885,47.50566],[19.15866,47.50493],[19.15793,47.50438],[19.10292,47.49828],[19.1016,47.49846],[19.10057,47.49914],[19.09185,47.5003],[19.08953,47.50117],[19.07138,47.51722],[19.06794,47.51558],[19.06631,47.51529],[19.06522,47.51545],[19.06347,47.51668],[19.06072,47.51512],[19.05709,47.51044],[19.05567,47.50992],[19.05417,47.50997],[19.04318,47.51383],[19.04093,47.51397],[19.04045,47.51449],[19.03916,47.51909],[19.03898,47.52143],[19.03938,47.52358],[19.04081,47.52649],[19.0408,47.53092],[19.02088,47.53091],[19.02088,47.529],[19.0172,47.52866],[19.01684,47.52876],[19.01453,47.53356],[19.01459,47.5347],[19.01373,47.5348],[19.01167,47.53786],[19.01055,47.53839],[19.0051,47.53978],[19.00501,47.54075],[19.00761,47.54245],[19.00684,47.54297],[19.00684,47.54385],[19.00525,47.54499],[19.0053,47.5455],[19.00462,47.54557],[19.00434,47.54599],[19.00261,47.55075],[18.99714,47.55468],[18.99466,47.55877],[18.99244,47.5605],[18.99173,47.56266],[18.99105,47.56278],[18.986,47.56863],[18.97914,47.57257],[18.97675,47.57301],[18.97622,47.57444],[18.97677,47.57463],[18.97641,47.57596],[18.98247,47.58127],[18.98227,47.58198],[18.98276,47.58283],[18.97695,47.58448],[18.97645,47.58485],[18.97639,47.58555],[18.98285,47.58936],[18.9841,47.58929],[18.99076,47.58612],[18.99375,47.58507],[18.99618,47.58645],[18.99727,47.58664],[19.00068,47.58457],[19.0016,47.58438],[19.00892,47.58637],[19.01088,47.58637],[19.01088,47.5869],[19.01264,47.58738],[19.02151,47.58876],[19.02593,47.58914],[19.03271,47.5883],[19.03199,47.59087],[19.03113,47.59163],[19.03125,47.59276],[19.02883,47.59838],[19.02808,47.59978],[19.0239,47.60425],[19.02393,47.60498],[19.02531,47.60575],[19.03768,47.6104],[19.04642,47.61098]]],"terms_url":"http://interspect.hu/","terms_text":"Interspect Kft.","best":true},{"id":"bartholomew_qi1940","name":"Ireland Bartholomew Quarter-Inch 1940","type":"tms","template":"http://geo.nls.uk/maps/ireland/bartholomew/{zoom}/{x}/{-y}.png","scaleExtent":[5,13],"polygon":[[[-8.8312773,55.3963337],[-7.3221271,55.398605],[-7.2891331,55.4333162],[-7.2368042,55.4530757],[-7.18881,55.4497995],[-7.1528144,55.3968384],[-6.90561,55.394903],[-6.9047153,55.3842114],[-5.8485282,55.3922956],[-5.8378629,55.248676],[-5.3614762,55.2507024],[-5.3899172,53.8466464],[-5.8734141,53.8487436],[-5.8983,52.8256258],[-6.0191742,52.8256258],[-6.0262844,51.7712367],[-8.1131422,51.7712367],[-8.1273627,51.3268839],[-10.6052842,51.3091083],[-10.6271879,52.0328254],[-10.6469845,52.0322454],[-10.6469845,52.0440365],[-10.6271879,52.0448095],[-10.6290733,52.0745627],[-10.6699234,52.0743695],[-10.6702376,52.0876941],[-10.6312729,52.0898179],[-10.6393128,52.4147202],[-10.3137689,52.4185533],[-10.3166401,53.3341342],[-10.3699669,53.3330727],[-10.385965,54.3534472],[-8.8163777,54.3586265],[-8.8173427,54.6595721],[-8.8413398,54.6616284],[-8.8422286,54.6929749],[-8.8315632,54.7145436],[-8.8151208,54.7145436],[-8.8312773,55.3963337]]],"terms_url":"http://geo.nls.uk/maps/","terms_text":"National Library of Scotland Historic Maps"},{"id":"GSGS3906","name":"Ireland British War Office 1:25k GSGS 3906","type":"tms","template":"http://mapwarper.net/layers/tile/101/{zoom}/{x}/{y}.png","scaleExtent":[0,18],"polygon":[[[-10.71,51.32],[-10.71,55.46],[-5.37,55.46],[-5.37,51.32],[-10.71,51.32]]],"terms_url":"http://wiki.openstreetmap.org/wiki/WikiProject_Ireland#Trinity_College_Dublin","terms_text":"Glucksman Map Library, Trinity College Dublin"},{"id":"GSGS4136","name":"Ireland British War Office One-Inch 1941-43 GSGS 4136","type":"tms","template":"http://geo.nls.uk/maps/ireland/gsgs4136/{zoom}/{x}/{-y}.png","scaleExtent":[5,15],"polygon":[[[-10.0847426,51.4147902],[-10.0906535,51.5064103],[-10.4564222,51.5003961],[-10.5005905,52.3043019],[-10.0837522,52.312741],[-10.0840973,52.3404698],[-10.055802,52.3408915],[-10.0768509,52.7628238],[-9.7780248,52.7684611],[-9.7818205,52.8577261],[-9.6337877,52.8596012],[-9.6449626,53.1294502],[-10.0919663,53.1227152],[-10.1051422,53.3912913],[-10.4052593,53.3866349],[-10.4530828,54.193502],[-10.2998523,54.1974988],[-10.3149801,54.4669592],[-8.9276095,54.4853897],[-8.9339534,54.7546562],[-8.7773069,54.755501],[-8.7826749,55.0252208],[-8.9402974,55.0238221],[-8.9451773,55.2934155],[-7.528039,55.2970274],[-7.525599,55.3874955],[-7.0541955,55.3841691],[-7.0556595,55.2939712],[-6.3241545,55.2859128],[-6.3217146,55.3253556],[-6.1035807,55.3223016],[-6.1045566,55.2828557],[-5.7985836,55.2772968],[-5.8117595,55.0087135],[-5.656577,55.0056351],[-5.6721928,54.7355021],[-5.3618278,54.729585],[-5.3964755,54.1917889],[-5.855679,54.2017807],[-5.9220464,52.8524504],[-6.070885,52.8551025],[-6.1030927,52.1373337],[-6.8331336,52.1463183],[-6.8355736,52.0578908],[-7.5641506,52.0617913],[-7.5661026,51.7921593],[-8.147305,51.792763],[-8.146329,51.7033331],[-8.2912636,51.7027283],[-8.2897996,51.5227274],[-9.1174397,51.516958],[-9.1179277,51.4625685],[-9.3692452,51.4616564],[-9.3672933,51.4254613],[-10.0847426,51.4147902]]],"terms_url":"http://geo.nls.uk/maps/","terms_text":"National Library of Scotland Historic Maps"},{"id":"IrelandEEACORINE2006","name":"Ireland EEA CORINE 2006","type":"tms","template":"http://a.tile.openstreetmap.ie/tiles/corine/{zoom}/{x}/{y}.png","scaleExtent":[5,16],"polygon":[[[-5.842956,53.8627976],[-5.8341575,53.7633541],[-5.6267647,53.5383692],[-5.9648778,52.1631197],[-6.0453211,52.0527275],[-6.1823261,51.9699475],[-6.3960035,51.9234618],[-6.5945978,51.883911],[-7.2481994,51.9056295],[-7.341212,51.8148076],[-8.1971787,51.5037019],[-8.3191005,51.4167737],[-9.4478202,51.1991221],[-9.9015706,51.2266802],[-10.472215,51.4050139],[-10.8857437,51.6770619],[-11.035318,52.0620016],[-10.9950963,52.1831616],[-10.8178697,52.3139827],[-9.8839736,52.9032208],[-10.1165049,52.9676141],[-10.5514014,53.3317027],[-10.6896633,53.5854022],[-10.6444139,54.0100436],[-10.5501445,54.257482],[-10.2824192,54.4742405],[-9.8073011,54.5705346],[-9.196435,54.5486695],[-9.2253443,54.7000264],[-8.8985435,55.1363582],[-8.0476045,55.4711977],[-7.4367384,55.6191092],[-7.2205471,55.6205288],[-6.8258723,55.5608644],[-6.0679458,55.3727567],[-5.5639184,55.0759594],[-5.0649187,54.4640142],[-5.2572284,54.1582424],[-5.842956,53.8627976]]],"terms_url":"http://www.eea.europa.eu/data-and-maps/data/clc-2006-vector-data-version-1","terms_text":"EEA Corine 2006"},{"id":"IrelandEEAGMESUrbanAtlas","name":"Ireland EEA GMES Urban Atlas","type":"tms","template":"http://a.tile.openstreetmap.ie/tiles/urbanatlas/{zoom}/{x}/{y}.png","scaleExtent":[5,17],"polygon":[[[-9.2759602,52.7993666],[-9.215509,52.8276933],[-9.1086618,52.9128016],[-9.0196831,52.8837107],[-8.8760649,52.8978445],[-8.8001797,52.8833558],[-8.7665597,52.9065354],[-8.5938079,52.9238592],[-8.5241972,52.8869724],[-8.4956786,52.9105906],[-8.3506448,52.9238592],[-8.2718204,52.9492401],[-8.2249679,52.8991338],[-8.1564001,52.9149986],[-8.0881237,52.7630417],[-8.1360092,52.7239783],[-8.1570652,52.6766443],[-8.2059695,52.6185385],[-8.2025734,52.5954396],[-8.2231242,52.5599691],[-8.2236294,52.5095371],[-8.2976651,52.5025088],[-8.3295888,52.4721087],[-8.3589695,52.4986072],[-8.3737385,52.4764529],[-8.432326,52.4342609],[-8.4754569,52.4216289],[-8.5017727,52.3870011],[-8.5476205,52.3681351],[-8.6444103,52.3376422],[-8.6841451,52.3660614],[-8.8154099,52.3721014],[-8.8614233,52.3521652],[-8.9074451,52.3824674],[-8.9388551,52.3789166],[-8.9782502,52.4093811],[-9.0298715,52.4104169],[-9.1059449,52.420981],[-9.1084962,52.4415071],[-9.140702,52.4650891],[-9.1315765,52.5136207],[-9.1739699,52.5620573],[-9.1426235,52.589645],[-9.1542382,52.610216],[-9.1426231,52.6387401],[-9.1776844,52.6447573],[-9.2012184,52.6526248],[-9.2036198,52.6686468],[-9.2238348,52.6706578],[-9.2161072,52.6919412],[-9.1882395,52.7057242],[-9.2750099,52.7350292],[-9.2601152,52.7616711],[-9.2759602,52.7993666]],[[-7.307313219981238,53.81625879275365],[-7.245858447032101,53.78300449111207],[-7.15144468970801,53.81179938127503],[-7.086900011973722,53.784424420834],[-7.0347149533800435,53.77996162275688],[-6.975320116954343,53.788481098127924],[-6.928628222423156,53.81443454540607],[-6.992829577403537,53.86609081229548],[-6.975320116954343,53.87945028968944],[-6.949914233165313,53.87094929783329],[-6.9375546140247035,53.87540241385127],[-6.936867968516893,53.896649390754646],[-6.897042529063821,53.889770599553906],[-6.867516772227924,53.880259817835736],[-6.851037280040446,53.88450958346468],[-6.842454211192801,53.89786317755242],[-6.812928454356904,53.90069520963246],[-6.79850889869286,53.89280549994937],[-6.789925829845217,53.89462633440526],[-6.791985766368652,53.904538374710896],[-6.778939501720231,53.918087767078354],[-6.77001311011868,53.91505470292794],[-6.75868345923979,53.921727153244476],[-6.744263903575747,53.916065748791254],[-6.727441088634364,53.92334455637637],[-6.713021532970319,53.90777445003927],[-6.684182421642232,53.90292024303218],[-6.623757616954815,53.88187882710815],[-6.590455309825955,53.857789593974296],[-6.591141955333765,53.835509894663346],[-6.574319140392382,53.82254170362619],[-6.571572558361136,53.804703885117576],[-6.5533764524041285,53.79983770791046],[-6.541360156017425,53.78300449111207],[-6.511491076427622,53.76900546961285],[-6.472695605236269,53.77326653566421],[-6.443513171154276,53.76393220797015],[-6.44728972144724,53.75114486961979],[-6.4775021237909485,53.728199094666586],[-6.459649340587848,53.71682309412751],[-6.435616747814443,53.72230833571077],[-6.4198239011347775,53.72921465935537],[-6.4009411496699595,53.72169889975152],[-6.375878588634836,53.718042098526006],[-6.359055773693453,53.708695495259434],[-6.340173022228636,53.708085862042424],[-6.329873339611461,53.71296268045594],[-6.325753466564592,53.72210519137233],[-6.2938244504513525,53.72576163932632],[-6.265328661877173,53.7363229253304],[-6.240952746349864,53.734292114843086],[-6.180871264416349,53.632015710147016],[-6.092793818322125,53.588038288422446],[-5.985734079608837,53.49383447350347],[-6.0887447432153685,53.27174268379562],[-6.033272979232964,53.1191110041494],[-5.984663357119282,52.9651254915577],[-6.122679104189409,52.73207538466633],[-6.185163845400262,52.73706461957944],[-6.1899703639549415,52.76075568810044],[-6.319059719423517,52.782357357522855],[-6.393904079774976,52.7790347214105],[-6.465315212587381,52.6946379192593],[-6.534666408876349,52.673409093161446],[-6.612257351259057,52.69255711803012],[-6.6692489284074155,52.74745702505679],[-6.671308864930852,52.76948072949997],[-6.720747341493285,52.7748810695361],[-6.71456753192298,52.80311808637125],[-6.658949245790243,52.84709806982182],[-6.582044948915348,52.81349473557279],[-6.547712673524768,52.83133677935633],[-6.531233181337292,52.87404491274922],[-6.617750515321548,52.87528820923615],[-6.728987087587023,52.90635903963372],[-6.780485500672891,52.859122574848655],[-6.870436062196207,52.85165948109425],[-6.938413967469552,52.86658438536895],[-6.965879787782016,52.89766145203082],[-6.987852444031986,52.969260966642985],[-7.039350857117853,52.9560260536776],[-7.109388698914634,53.007288776633686],[-7.068876613953752,53.058078015357786],[-7.088789333680287,53.11869890949892],[-7.119688381531809,53.15000684568904],[-7.105955471375577,53.16112391039828],[-7.127928127625547,53.17223809655703],[-7.180113186219227,53.182526443342745],[-7.160887112000503,53.19898266621498],[-7.057890285828767,53.19898266621498],[-7.048963894227218,53.217077217179636],[-7.0915359157115345,53.235575105358386],[-7.0434707301647235,53.25735126035676],[-7.05102383075065,53.29717703664696],[-6.996778835633536,53.31112780504489],[-7.044157375672535,53.33368557548294],[-7.105955471375576,53.371801590024276],[-7.22050647653913,53.432465115081854],[-7.149441429887032,53.45731709817442],[-7.099891489102085,53.463915962572514],[-7.0744645458045445,53.48370640260363],[-7.079028356140001,53.504650927752664],[-7.047733656696876,53.515119311359335],[-7.029478415355053,53.54147267392419],[-7.054253385747527,53.56471202500164],[-7.009267255298033,53.58561652973758],[-6.992641946218873,53.602642188744426],[-6.989056095241016,53.62739453790707],[-6.9717788132567895,53.63686620586593],[-6.9633031654909425,53.650973114934644],[-6.9871001765258205,53.66623418009986],[-6.999813648174589,53.67086935885432],[-7.008289295940436,53.65908728051006],[-7.044473792171549,53.65367801032349],[-7.066640870943764,53.63918547390694],[-7.101847407817279,53.65870092708686],[-7.120754622064167,53.672993645380515],[-7.137379931143327,53.66893809633893],[-7.160850955725672,53.683034277255075],[-7.174216400279507,53.686316272406906],[-7.196057492599188,53.69017711570491],[-7.210726882963154,53.69480966037566],[-7.247237365646801,53.71661437518035],[-7.239413690786019,53.73223735177976],[-7.260276823748104,53.74361339729716],[-7.2814659431627184,53.75922634307083],[-7.289615604476034,53.77271433845693],[-7.3238441819919515,53.78465723043301],[-7.337209626545788,53.78658318504567],[-7.351227044004687,53.80141007448381],[-7.307313219981238,53.81625879275365]],[[-5.685433013282673,54.77854496390836],[-5.696867084279401,54.73050346921268],[-5.8223689524230124,54.70033215177621],[-5.878760568989772,54.649492182564074],[-5.743404719024681,54.68128223623249],[-5.581196917402638,54.68781619319656],[-5.571488953592992,54.67074450064368],[-5.582915011231644,54.66440901595977],[-5.58291501123164,54.65085746679818],[-5.6086481910584185,54.63997082553691],[-5.6354970593650116,54.61551371292451],[-5.728732824433139,54.6184944610979],[-5.822612969913913,54.49193018941315],[-5.896754545381575,54.44975600798866],[-5.936834914186871,54.38213187386197],[-6.0187561190025445,54.36974944197913],[-6.059257912638059,54.38280030737259],[-6.101784280694663,54.41510088826871],[-6.1740201072375225,54.43476829635816],[-6.216261364689026,54.42827259213158],[-6.264329002478664,54.487825014814625],[-6.249277519938476,54.49741303545491],[-6.288340515296785,54.53143435197413],[-6.283750270272458,54.54447449434036],[-6.321445027854273,54.58928767713928],[-6.264329002478664,54.604982769755765],[-6.240052417736423,54.59541999854735],[-6.098762694536575,54.631690374598676],[-6.051950538018501,54.61314575326238],[-6.031509408441251,54.620921248201434],[-6.002995140908084,54.65571636730639],[-6.0647754758974335,54.6634355452454],[-6.059920158948984,54.704134188139534],[-6.047781866577864,54.71395188569398],[-6.120611620804591,54.801644524994515],[-6.002141887262449,54.80836072138932],[-5.984662746248036,54.78652900156178],[-5.685433013282673,54.77854496390836]],[[-9.128658300749114,53.24759266864586],[-9.024510568479629,53.26744820137083],[-9.016360907166316,53.26364619217274],[-9.001854510028616,53.26588844362053],[-8.9951717877517,53.259258838409615],[-8.973493688658284,53.262378780650025],[-8.95230456924367,53.271444820907114],[-8.956705386352859,53.281580911863244],[-8.961106203462048,53.28119110665652],[-8.960780217009516,53.28908396911955],[-8.954260487958864,53.28927883616923],[-8.95230456924367,53.30155366854246],[-8.963714095082308,53.303793931840495],[-8.9811543702928,53.294734752711804],[-8.985718180628256,53.30174847871221],[-9.019946758144176,53.30768976199425],[-9.00837423907927,53.31596722087059],[-9.01880580556031,53.31625933715475],[-9.045862681120513,53.31275380979257],[-9.06444390891487,53.32122500810515],[-9.080906224767762,53.307397587062724],[-9.08106921799403,53.303404329274585],[-9.09019683866494,53.30574189135002],[-9.095901601584261,53.298826232852214],[-9.10128037805105,53.3008718259498],[-9.115623781962478,53.28450433758295],[-9.121491538108067,53.2832375443259],[-9.13273807072044,53.28557621023763],[-9.144636576237877,53.27865728614638],[-9.13876882009229,53.26345120822951],[-9.128658300749114,53.24759266864586]],[[-8.595266214281438,51.69264788483154],[-8.55819409885298,51.69306638852667],[-8.566697711835303,51.682644706464686],[-8.579130708100188,51.67349700898941],[-8.544554623426079,51.66520531197343],[-8.494765061495364,51.667778759675976],[-8.30113898732036,51.7235009029955],[-8.268406960495541,51.784858633837544],[-8.154536388302146,51.7814362126791],[-8.115350159004825,51.809093351533164],[-8.068326683848039,51.870050153657075],[-8.10059769621054,51.89964422561186],[-8.08123508879304,51.918414974037226],[-8.09183842142643,51.95337589170907],[-8.124570448251253,51.95479649105758],[-8.132407694110718,51.970988142592034],[-8.099675667285895,51.978371865876596],[-8.144394070131078,52.02151390085561],[-8.159607547387685,52.064330945363764],[-8.140705954432507,52.07254939152303],[-8.165600735397863,52.09294727054506],[-8.18726841512697,52.0835993998731],[-8.2093971093184,52.10512489114057],[-8.207092037006792,52.12494181389489],[-8.227837687811258,52.143052434929714],[-8.222766528725723,52.16454923557058],[-8.30298304516965,52.1829264222872],[-8.427456949996438,52.17783811526099],[-8.46710419375608,52.169921813849676],[-8.509978538751975,52.18405707812542],[-8.530263175094117,52.16511480067495],[-8.574981577939297,52.18066502436804],[-8.587889982884295,52.16963906274442],[-8.642289689438227,52.18829678149147],[-8.719279104645906,52.15804472022032],[-8.698533453841442,52.13541291452849],[-8.740946784375014,52.10823956240069],[-8.77460084012448,52.05951253229793],[-8.803183736788409,52.03768144571248],[-8.86818677597573,52.03286015807593],[-8.870491848287335,52.01839317543363],[-8.844214023935015,51.991148511559096],[-8.79811257770287,51.964455373040394],[-8.782899100446263,51.931777239822054],[-8.835915763613228,51.9292188160068],[-8.838681850387156,51.90277322850554],[-8.802261707863764,51.89367006943167],[-8.792580404155013,51.85695425263326],[-8.765841565340368,51.82476769939557],[-8.758926348405547,51.80054140901511],[-8.79811257770287,51.78628456602828],[-8.832227647914657,51.79626482935233],[-8.836837792537873,51.77687258059678],[-8.885705325543944,51.746055989869106],[-8.859888515653944,51.72435763090916],[-8.807332866949299,51.71093369500414],[-8.678248817499297,51.693505197270746],[-8.60540853245251,51.67835695335278],[-8.595266214281438,51.69264788483154]],[[-7.138279151048154,55.06131559970097],[-7.117994514706011,54.99631329558348],[-7.070049010624583,54.98784996056705],[-7.076503213097081,54.93332450204895],[-7.025791622241725,54.91159959910791],[-7.007351043748867,54.87872502112528],[-7.024869593317081,54.8511320998998],[-6.990754523105296,54.81661438893913],[-7.051608432131725,54.80598761598125],[-7.115228427932084,54.80651902101645],[-7.170550163410654,54.84847793920564],[-7.199133060074584,54.84316909395457],[-7.222183783190655,54.85803210052931],[-7.2111194360949415,54.862808332627324],[-7.212041465019584,54.882438010878076],[-7.279349576518514,54.880846771447125],[-7.273817402970655,54.91530955931841],[-7.3033223285592275,54.915839525718205],[-7.363254208661015,54.90894941815292],[-7.385382902852443,54.91636948513913],[-7.391837105324943,54.93438395336098],[-7.429640291235302,54.95291983389722],[-7.420420001988872,54.99208185118366],[-7.410277683817801,55.03437621938347],[-7.3577220351131585,55.057619110599035],[-7.265519142648871,55.07557028899173],[-7.138279151048154,55.06131559970097]],[[-7.190498776293322,52.26144368927652],[-7.156844720543858,52.28443443581867],[-7.132871968503143,52.27343421670601],[-7.113278853854483,52.26779201951648],[-7.098295883829036,52.27230583471742],[-7.089767116276089,52.25509445009032],[-7.07109603055207,52.259186286149074],[-7.033984366335195,52.257352061495865],[-7.027530163862696,52.250720000975015],[-7.034675888028678,52.247756419376],[-7.031218279561267,52.24013487190721],[-7.034214873566356,52.23222966213934],[-7.050580886978767,52.2296884028405],[-7.062567262999124,52.21980434486687],[-7.076858711331088,52.216132562953725],[-7.084926464421715,52.22065163604718],[-7.084465449959392,52.22785295843095],[-7.101292477834124,52.221498911062525],[-7.105211100763858,52.21726237433474],[-7.111665303236357,52.21796849185403],[-7.107977187537785,52.21104805609072],[-7.117773744862115,52.20928246619701],[-7.129760120882472,52.21690931136535],[-7.14497359813908,52.21782726924826],[-7.150505771686938,52.22375823207553],[-7.158112510315241,52.22262858593765],[-7.158804032008724,52.22700580464912],[-7.158573524777563,52.23180612902503],[-7.167563306792832,52.23985256723076],[-7.16733279956167,52.244580933687786],[-7.172519212262786,52.24676851484933],[-7.177590371348324,52.25114335361416],[-7.190498776293322,52.26144368927652]]],"terms_url":"http://www.eea.europa.eu/data-and-maps/data/urban-atlas","terms_text":"EEA GMES Urban Atlas"},{"id":"gsi.go.jp","name":"Japan GSI ortho Imagery","type":"tms","template":"http://cyberjapandata.gsi.go.jp/xyz/ort/{zoom}/{x}/{y}.jpg","scaleExtent":[12,19],"polygon":[[[141.85546875,44.64911632343077],[140.2294921875,43.96909818325174],[138.955078125,41.80407814427237],[139.482421875,40.17887331434696],[138.8671875,38.30718056188316],[136.31835937499997,37.19533058280065],[132.1435546875,35.137879119634185],[128.935546875,33.35806161277885],[129.5068359375,32.47269502206151],[129.77050781249997,31.690781806136822],[130.2099609375,30.90222470517144],[131.220703125,30.78903675126116],[131.66015625,32.32427558887655],[132.71484375,32.879587173066305],[133.76953125,33.17434155100208],[136.7578125,33.87041555094183],[139.306640625,35.06597313798418],[140.888671875,35.17380831799959],[141.15234374999997,36.56260003738548],[142.11914062499997,39.9434364619742],[141.767578125,42.68243539838623],[141.85546875,44.64911632343077]]]},{"id":"Aargau-AGIS-2011","name":"Kanton Aargau 25cm (AGIS 2011)","type":"tms","template":"http://tiles.poole.ch/AGIS/OF2011/{zoom}/{x}/{y}.png","scaleExtent":[14,19],"polygon":[[[7.7,47.12],[7.7,47.63],[8.5,47.63],[8.5,47.12],[7.7,47.12]]],"terms_text":"AGIS OF2011"},{"id":"Aargau-AGIS-2014","name":"Kanton Aargau 25cm (AGIS 2014)","type":"tms","template":"http://mapproxy.osm.ch:8080/tiles/AGIS2014/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","scaleExtent":[8,19],"polygon":[[[8.222923278808594,47.604774168947614],[8.244209289550781,47.613569753973955],[8.294334411621094,47.60986653003798],[8.300857543945312,47.58625231278527],[8.329353332519531,47.569808674020344],[8.382568359375,47.56702895728551],[8.398017883300781,47.57490443821351],[8.424797058105469,47.56795554592218],[8.415184020996094,47.54663986006874],[8.389778137207031,47.5262428287156],[8.372268676757812,47.51233121261258],[8.358535766601562,47.503286684046664],[8.36402893066406,47.48078455918],[8.371238708496094,47.481016589036074],[8.373985290527344,47.47011007802331],[8.368148803710938,47.46825342516445],[8.387031555175781,47.44852243794931],[8.380851745605469,47.447593738482304],[8.384284973144531,47.4355191531953],[8.376388549804688,47.431803338643334],[8.377761840820312,47.42808726171425],[8.389434814453125,47.42739046807988],[8.391494750976562,47.41902822496511],[8.380165100097656,47.40462347023052],[8.364715576171875,47.4016026187529],[8.367118835449219,47.39881398671558],[8.380851745605469,47.39788440990287],[8.39424133300781,47.39439835079049],[8.399734497070312,47.372314620566925],[8.40728759765625,47.37068703239024],[8.404197692871094,47.34417352612498],[8.416213989257812,47.33416935720614],[8.414497375488281,47.32602502961836],[8.452606201171875,47.33254059215931],[8.444023132324219,47.31927592106609],[8.427543640136719,47.29925625338924],[8.390121459960938,47.28854494625744],[8.41175079345703,47.247076403108416],[8.393898010253906,47.227728840642065],[8.404884338378906,47.194845099780174],[8.401451110839844,47.17757880776958],[8.409690856933594,47.17314466448546],[8.412437438964844,47.13976002139446],[8.379478454589844,47.13929295458033],[8.361968994140625,47.14559801038333],[8.342742919921875,47.177112073280966],[8.3056640625,47.24987305653909],[8.295021057128906,47.26268916206698],[8.300514221191406,47.26991141830738],[8.278884887695312,47.28225686421767],[8.259315490722656,47.285983225286174],[8.243522644042969,47.280859411143915],[8.240432739257812,47.27130916053537],[8.228759765625,47.27270686584952],[8.219146728515625,47.25336866567523],[8.204727172851562,47.245444953748034],[8.203353881835938,47.22679624955806],[8.180007934570312,47.22143353240336],[8.171768188476562,47.2279619858493],[8.155975341796875,47.23961793870555],[8.175888061523436,47.24218190428504],[8.17657470703125,47.25406775981567],[8.136062622070312,47.24730946320093],[8.12164306640625,47.24218190428504],[8.10791015625,47.2447457457832],[8.097267150878906,47.259427174956194],[8.077354431152344,47.2603591917818],[8.059844970703125,47.25569894358661],[8.062591552734375,47.24614415248379],[8.016586303710938,47.242881146090085],[8.015899658203125,47.258961160390896],[7.997016906738281,47.2796948387185],[7.951698303222655,47.274337475394645],[7.960968017578125,47.25430078914495],[7.933845520019531,47.237053849043896],[7.911529541015624,47.24381345414034],[7.859344482421875,47.23425651880584],[7.83977508544922,47.23425651880584],[7.826042175292968,47.24427960201268],[7.828102111816407,47.25966018070071],[7.82398223876953,47.26548499105541],[7.8408050537109375,47.273405704663965],[7.848701477050781,47.28551744450745],[7.860374450683594,47.30461109337307],[7.871704101562499,47.31136207506936],[7.8888702392578125,47.31136207506936],[7.897453308105469,47.31904317780638],[7.895393371582031,47.327653995607086],[7.908439636230469,47.340451266106996],[7.9259490966796875,47.332773275955894],[7.94757843017578,47.331609846720866],[7.94757843017578,47.316715688820764],[8.007316589355467,47.33905535093827],[8.004913330078125,47.34533667855891],[8.011093139648438,47.35719936945847],[8.024139404296875,47.36719917429931],[8.032722473144531,47.38393878966209],[8.026885986328125,47.39602520707679],[8.010749816894531,47.3955603961201],[8.004570007324219,47.40671472747142],[7.975730895996094,47.41507892620099],[7.9657745361328125,47.42181578692778],[7.985343933105469,47.425764580393924],[7.971954345703124,47.46105827584221],[7.957534790039062,47.457344265054225],[7.940711975097656,47.46221885041022],[7.946891784667968,47.48403288391224],[7.907066345214844,47.48588897929538],[7.8936767578125,47.50653361720931],[7.873420715332031,47.51325876844644],[7.875480651855468,47.52253342509336],[7.865180969238281,47.51975120023913],[7.856254577636718,47.533660849056794],[7.833251953125,47.5325018525392],[7.834281921386719,47.51465007145751],[7.789649963378906,47.49377665301097],[7.789649963378906,47.518128167602484],[7.7515411376953125,47.52461999690649],[7.731285095214843,47.53203824675999],[7.708969116210937,47.54015075619555],[7.740898132324219,47.54362716173679],[7.761497497558593,47.54895720250044],[7.781410217285156,47.55289644950155],[7.797546386718749,47.55915229204993],[7.805442810058593,47.56563904359584],[7.814369201660155,47.575136052077276],[7.819175720214843,47.58648387645128],[7.8325653076171875,47.586715439092906],[7.843208312988281,47.581620824334166],[7.859344482421875,47.58602074809481],[7.8847503662109375,47.58764167941513],[7.903633117675781,47.58092606572345],[7.911872863769532,47.56749225365282],[7.90740966796875,47.55776216936179],[7.917709350585938,47.545712894408624],[7.929382324218749,47.54640812019053],[7.941741943359374,47.54432241518175],[7.9520416259765625,47.54965238525127],[7.9561614990234375,47.55683540041267],[7.9767608642578125,47.55544521625339],[7.997360229492187,47.556603705614094],[8.019676208496094,47.54965238525127],[8.049888610839844,47.55637200979099],[8.058815002441406,47.56285910557121],[8.072891235351562,47.56355410390809],[8.086967468261719,47.557067094186735],[8.100700378417969,47.56216409801383],[8.105506896972656,47.57976811421671],[8.113059997558594,47.583473468887405],[8.133659362792969,47.58301031389572],[8.138809204101562,47.59042030203756],[8.15185546875,47.59551406038282],[8.166275024414062,47.5941249027327],[8.177261352539062,47.6017648134425],[8.193740844726562,47.616346999837226],[8.2012939453125,47.62120682516921],[8.219490051269531,47.61958693358351],[8.223953247070312,47.61102381568743],[8.222923278808594,47.604774168947614]]],"terms_text":"AGIS OF2014","best":true},{"id":"KTBASELSTADT2015","name":"Kanton Basel-Stadt 2015","type":"tms","template":"http://mapproxy.osm.ch:8080/tiles/KTBASELSTADT2015/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","scaleExtent":[8,21],"polygon":[[[7.492,47.4817],[7.492,47.6342],[7.784,47.6342],[7.784,47.4817],[7.492,47.4817]]],"terms_text":"Kanton Basel-Stadt OF 2015"},{"id":"Solothurn-sogis2014-tms","name":"Kanton Solothurn 25cm (SOGIS 2014-2015)","type":"tms","template":"http://mapproxy.osm.ch:8080/tiles/sogis2014/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","scaleExtent":[12,19],"polygon":[[[7.3404127,47.2175697],[7.4154818,47.2402115],[7.4173645,47.2537956],[7.4658424,47.2646513],[7.4946766,47.2882287],[7.5328638,47.294534],[7.5483333,47.3163566],[7.5709479,47.3263111],[7.5604584,47.342492],[7.5388991,47.3476266],[7.5396485,47.3601134],[7.5217459,47.3651488],[7.5237238,47.3720704],[7.4634937,47.3702566],[7.4361035,47.3781317],[7.4434011,47.4023143],[7.4774682,47.4012772],[7.4792364,47.3897076],[7.5022557,47.384807],[7.5213659,47.3912021],[7.5311724,47.4035251],[7.5252352,47.4116329],[7.5807413,47.414704],[7.5682954,47.4223349],[7.5689044,47.436897],[7.5812069,47.4287807],[7.6157989,47.4327479],[7.6260723,47.4629139],[7.6044949,47.4704455],[7.6072998,47.4893984],[7.640966,47.4827341],[7.6559259,47.4873946],[7.6521711,47.4958144],[7.6661209,47.4968682],[7.6683266,47.4863467],[7.699761,47.4806325],[7.709878,47.4693848],[7.6848538,47.4478436],[7.6798021,47.417514],[7.6327228,47.4100311],[7.633317,47.382914],[7.6417611,47.3804694],[7.6442033,47.3672084],[7.7279138,47.3688589],[7.751519,47.3443275],[7.7935609,47.3390523],[7.8021665,47.3610959],[7.8788122,47.3835105],[7.8691367,47.3955143],[7.883332,47.4060973],[7.9097377,47.398521],[7.9550377,47.4156057],[7.9618317,47.4218343],[7.9467846,47.4431934],[7.9682836,47.4628082],[7.9872707,47.4287435],[7.9854653,47.4227641],[7.9827035,47.4283325],[7.9631993,47.4223547],[8.0072617,47.4065858],[8.0100022,47.395418],[8.0265612,47.3956224],[8.0313669,47.3836856],[8.0038366,47.3453146],[8.0051906,47.3367516],[7.9479701,47.3171432],[7.9478307,47.3325169],[7.9192088,47.3339507],[7.9078055,47.341719],[7.889098,47.3114878],[7.8611018,47.3061239],[7.8418057,47.2744707],[7.8166423,47.2616706],[7.8028241,47.2684079],[7.7861469,47.256098],[7.7746009,47.267869],[7.7568187,47.258095],[7.7326672,47.2591133],[7.684769,47.2939919],[7.6482742,47.2819898],[7.5801066,47.2763483],[7.5936981,47.2662199],[7.5959384,47.245569],[7.6261802,47.2263143],[7.6405558,47.2297944],[7.6484666,47.2189525],[7.6472258,47.2017823],[7.6715278,47.1949714],[7.6711002,47.1845216],[7.6779881,47.1819259],[7.6728612,47.1683945],[7.6600808,47.1684026],[7.6451021,47.1489207],[7.6155322,47.1565739],[7.5861404,47.1475453],[7.5810534,47.16013],[7.5634674,47.1683541],[7.5257686,47.162205],[7.5203336,47.1588879],[7.5297508,47.1487369],[7.5097234,47.1255457],[7.4613252,47.1082327],[7.4750945,47.0867101],[7.454461,47.074927],[7.4354156,47.0801664],[7.4340002,47.1005003],[7.3820271,47.0957398],[7.3704914,47.1209312],[7.4401788,47.1237276],[7.4217922,47.1358605],[7.447783,47.1550805],[7.4728074,47.1525609],[7.4970383,47.1700873],[7.4804964,47.171738],[7.4708545,47.181324],[7.4757226,47.1906485],[7.4497638,47.1895691],[7.4476258,47.1810839],[7.4332849,47.1847269],[7.4118135,47.1624212],[7.3842442,47.1601249],[7.3821749,47.1651186],[7.391911,47.1662739],[7.3835137,47.1803011],[7.3654609,47.1944525],[7.3544799,47.1915316],[7.3404127,47.2175697]],[[7.420816,47.4803666],[7.4349836,47.4981011],[7.4707584,47.480734],[7.487277,47.4820136],[7.5116652,47.5026958],[7.5317892,47.4973989],[7.5366964,47.4850517],[7.5274454,47.4739062],[7.5306791,47.4611886],[7.4565122,47.4492558],[7.445214,47.4623781],[7.4557367,47.4733767],[7.420816,47.4803666]],[[7.3759458,47.4140995],[7.3821514,47.4330266],[7.4209041,47.4459442],[7.4378427,47.4463232],[7.4555765,47.4279232],[7.4437574,47.413444],[7.3759458,47.4140995]],[[7.6744234,47.1539707],[7.6853662,47.1662986],[7.7007985,47.1617746],[7.6901531,47.1525567],[7.6744234,47.1539707]]],"terms_text":"Orthofoto WMS Solothurn","best":true},{"id":"KTZUERICH2015","name":"Kanton Zürich 2015 10cm","type":"tms","template":"http://mapproxy.osm.ch:8080/tiles/KTZUERICH2015/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","scaleExtent":[8,21],"polygon":[[[8.807601928710938,47.66608099332474],[8.808631896972656,47.65475043477393],[8.830604553222656,47.648506014952225],[8.805885314941406,47.597597727711346],[8.749580383300781,47.61565270219988],[8.751983642578125,47.59505101193038],[8.807945251464844,47.585789182379905],[8.811721801757812,47.57467282332527],[8.840904235839844,47.57467282332527],[8.854637145996094,47.56216409801383],[8.8330078125,47.55382328811835],[8.845024108886719,47.53458802782819],[8.899612426757812,47.52786561031842],[8.895835876464844,47.491224888201955],[8.902702331542969,47.48588897929538],[8.887252807617188,47.475911695481756],[8.911285400390625,47.43969913094723],[8.934288024902344,47.43807362350206],[8.935317993164062,47.43017758727173],[8.917121887207031,47.42808726171425],[8.909912109375,47.404855836246135],[8.944587707519531,47.38905261221537],[8.945274353027344,47.379521907289295],[8.963127136230469,47.357664518690434],[8.973083496093748,47.35580389715929],[8.989906311035156,47.31857768821123],[8.973426818847656,47.30367985581531],[8.9593505859375,47.300653220457775],[8.941154479980469,47.2873805430142],[8.950080871582031,47.28458587064588],[8.940467834472656,47.259194168186234],[8.876266479492188,47.24847474828181],[8.876609802246092,47.243114224640834],[8.850173950195312,47.23961793870555],[8.849830627441406,47.247076403108416],[8.825111389160156,47.24824169331652],[8.800048828125,47.24031721435106],[8.804855346679688,47.23425651880584],[8.815155029296875,47.217702626593784],[8.793525695800781,47.21886856286133],[8.71490478515625,47.20021050593422],[8.685722351074219,47.18154588528182],[8.697395324707031,47.163108130899104],[8.660659790039062,47.15633823511178],[8.6572265625,47.16684287656919],[8.618087768554688,47.172444502751944],[8.622550964355469,47.17991241867412],[8.607101440429688,47.201376826785406],[8.595085144042969,47.19834433924206],[8.575859069824219,47.21513747655813],[8.541183471679688,47.2186353776589],[8.471488952636719,47.2053421258966],[8.441619873046875,47.22120035848172],[8.417243957519531,47.22120035848172],[8.383941650390625,47.292270864380086],[8.422050476074219,47.302282968719936],[8.442306518554688,47.32439601339355],[8.413810729980469,47.32299967378833],[8.408660888671875,47.33067908487908],[8.378448486328125,47.39718721653071],[8.360939025878906,47.39695481668995],[8.359222412109375,47.4053205652024],[8.379135131835938,47.40764414848437],[8.377418518066406,47.41624051540972],[8.384284973144531,47.42274494145051],[8.372611999511719,47.42808726171425],[8.372955322265625,47.437376962080776],[8.379478454589844,47.45037978769006],[8.36402893066406,47.46198673754625],[8.352012634277344,47.5079250985124],[8.373985290527344,47.517200697839414],[8.392181396484375,47.5366741201253],[8.417587280273436,47.56610235225701],[8.430290222167967,47.5693453981427],[8.491744995117188,47.581620824334166],[8.487625122070312,47.58648387645128],[8.463935852050781,47.58301031389572],[8.453292846679688,47.60315376826432],[8.479385375976562,47.617504142079596],[8.505821228027344,47.61958693358351],[8.513717651367188,47.635783590864854],[8.542213439941406,47.632776019724375],[8.545646667480469,47.627685889602006],[8.564186096191406,47.6256034207548],[8.566932678222656,47.61935551640258],[8.576202392578125,47.613569753973955],[8.564872741699219,47.60037582174319],[8.535346984863281,47.586715439092906],[8.550109863281248,47.5714301073211],[8.555259704589844,47.55498181333744],[8.581008911132812,47.59551406038282],[8.598861694335936,47.61449551898437],[8.59130859375,47.64642437575518],[8.609848022460938,47.65521295468833],[8.620834350585938,47.646886969413],[8.618431091308594,47.65660048985082],[8.602981567382812,47.666312203609145],[8.610877990722656,47.67856488312544],[8.62323760986328,47.67856488312544],[8.621864318847656,47.69312564683551],[8.64898681640625,47.697516190510555],[8.667526245117188,47.68665469810477],[8.671646118164062,47.67602211074509],[8.692245483398438,47.65197522925437],[8.734817504882812,47.64526787368664],[8.777389526367188,47.65313158281113],[8.785629272460938,47.667930646923494],[8.807601928710938,47.66608099332474]]],"terms_text":"Kanton Zürich OF 2015","best":true},{"id":"kelowna_2012","name":"Kelowna 2012","type":"tms","template":"http://{switch:a,b,c,d}.tile.paulnorman.ca/kelowna2012/{zoom}/{x}/{y}.png","description":"High quality aerial imagery taken for the City of Kelowna","scaleExtent":[9,20],"polygon":[[[-119.5867318,49.7928087],[-119.5465655,49.7928097],[-119.5465661,49.8013837],[-119.5343374,49.8013841],[-119.5343376,49.8047321],[-119.5296211,49.8047322],[-119.5296216,49.8119555],[-119.5104463,49.811956],[-119.5115683,49.8744325],[-119.5108946,49.8744904],[-119.5114111,49.8843312],[-119.5114115,49.9221763],[-119.49386,49.9223477],[-119.4940505,49.9313031],[-119.4803936,49.9317529],[-119.4804572,49.9407474],[-119.4666732,49.9409927],[-119.4692775,49.9913717],[-119.4551337,49.9916078],[-119.4556736,50.0121242],[-119.4416673,50.0123895],[-119.4417308,50.0136345],[-119.4221492,50.0140377],[-119.4221042,50.0119306],[-119.4121303,50.012165],[-119.4126082,50.0216913],[-119.4123387,50.0216913],[-119.4124772,50.0250773],[-119.4120917,50.0250821],[-119.4121954,50.0270769],[-119.4126083,50.0270718],[-119.4128328,50.0321946],[-119.3936313,50.0326418],[-119.393529,50.0307781],[-119.3795727,50.0310116],[-119.3795377,50.0287584],[-119.3735764,50.0288621],[-119.371544,49.9793618],[-119.3573506,49.9793618],[-119.3548353,49.9256081],[-119.3268079,49.9257238],[-119.3256573,49.8804068],[-119.3138893,49.8806528],[-119.3137097,49.8771651],[-119.3132156,49.877223],[-119.3131482,49.8749652],[-119.312452,49.8749073],[-119.3122275,49.87236],[-119.3117558,49.872331],[-119.3115986,49.8696098],[-119.3112169,49.8694217],[-119.3109199,49.8632417],[-119.3103721,49.8632724],[-119.3095139,49.8512388],[-119.3106368,49.8512316],[-119.3103859,49.8462564],[-119.3245344,49.8459957],[-119.3246018,49.8450689],[-119.3367018,49.844875],[-119.3367467,49.8435136],[-119.337937,49.8434702],[-119.3378023,49.8382055],[-119.3383637,49.8381041],[-119.3383749,49.8351202],[-119.3390936,49.8351058],[-119.3388016,49.8321217],[-119.3391497,49.8320565],[-119.3391722,49.8293331],[-119.3394641,49.8293331],[-119.3395879,49.8267878],[-119.3500053,49.8265829],[-119.3493701,49.8180588],[-119.4046964,49.8163785],[-119.4045694,49.8099022],[-119.4101592,49.8099022],[-119.4102862,49.8072787],[-119.4319467,49.8069098],[-119.4322643,49.7907965],[-119.4459847,49.7905504],[-119.445286,49.7820201],[-119.4967376,49.7811587],[-119.4966105,49.7784927],[-119.5418371,49.7775082],[-119.5415892,49.7718277],[-119.5560296,49.7714941],[-119.5561194,49.7718422],[-119.5715704,49.7715086],[-119.5716153,49.7717262],[-119.5819235,49.7714941],[-119.5820133,49.7717697],[-119.5922991,49.7715231],[-119.592344,49.7718132],[-119.6003839,49.7715957],[-119.6011924,49.7839081],[-119.5864365,49.7843863],[-119.5867318,49.7928087]]]},{"id":"kelowna_roads","name":"Kelowna Roads overlay","type":"tms","template":"http://{switch:a,b,c,d}.tile.paulnorman.ca/kelowna_overlay/{zoom}/{x}/{y}.png","scaleExtent":[9,20],"polygon":[[[-119.5867318,49.7928087],[-119.5465655,49.7928097],[-119.5465661,49.8013837],[-119.5343374,49.8013841],[-119.5343376,49.8047321],[-119.5296211,49.8047322],[-119.5296216,49.8119555],[-119.5104463,49.811956],[-119.5115683,49.8744325],[-119.5108946,49.8744904],[-119.5114111,49.8843312],[-119.5114115,49.9221763],[-119.49386,49.9223477],[-119.4940505,49.9313031],[-119.4803936,49.9317529],[-119.4804572,49.9407474],[-119.4666732,49.9409927],[-119.4692775,49.9913717],[-119.4551337,49.9916078],[-119.4556736,50.0121242],[-119.4416673,50.0123895],[-119.4417308,50.0136345],[-119.4221492,50.0140377],[-119.4221042,50.0119306],[-119.4121303,50.012165],[-119.4126082,50.0216913],[-119.4123387,50.0216913],[-119.4124772,50.0250773],[-119.4120917,50.0250821],[-119.4121954,50.0270769],[-119.4126083,50.0270718],[-119.4128328,50.0321946],[-119.3936313,50.0326418],[-119.393529,50.0307781],[-119.3795727,50.0310116],[-119.3795377,50.0287584],[-119.3735764,50.0288621],[-119.371544,49.9793618],[-119.3573506,49.9793618],[-119.3548353,49.9256081],[-119.3268079,49.9257238],[-119.3256573,49.8804068],[-119.3138893,49.8806528],[-119.3137097,49.8771651],[-119.3132156,49.877223],[-119.3131482,49.8749652],[-119.312452,49.8749073],[-119.3122275,49.87236],[-119.3117558,49.872331],[-119.3115986,49.8696098],[-119.3112169,49.8694217],[-119.3109199,49.8632417],[-119.3103721,49.8632724],[-119.3095139,49.8512388],[-119.3106368,49.8512316],[-119.3103859,49.8462564],[-119.3245344,49.8459957],[-119.3246018,49.8450689],[-119.3367018,49.844875],[-119.3367467,49.8435136],[-119.337937,49.8434702],[-119.3378023,49.8382055],[-119.3383637,49.8381041],[-119.3383749,49.8351202],[-119.3390936,49.8351058],[-119.3388016,49.8321217],[-119.3391497,49.8320565],[-119.3391722,49.8293331],[-119.3394641,49.8293331],[-119.3395879,49.8267878],[-119.3500053,49.8265829],[-119.3493701,49.8180588],[-119.4046964,49.8163785],[-119.4045694,49.8099022],[-119.4101592,49.8099022],[-119.4102862,49.8072787],[-119.4319467,49.8069098],[-119.4322643,49.7907965],[-119.4459847,49.7905504],[-119.445286,49.7820201],[-119.4967376,49.7811587],[-119.4966105,49.7784927],[-119.5418371,49.7775082],[-119.5415892,49.7718277],[-119.5560296,49.7714941],[-119.5561194,49.7718422],[-119.5715704,49.7715086],[-119.5716153,49.7717262],[-119.5819235,49.7714941],[-119.5820133,49.7717697],[-119.5922991,49.7715231],[-119.592344,49.7718132],[-119.6003839,49.7715957],[-119.6011924,49.7839081],[-119.5864365,49.7843863],[-119.5867318,49.7928087]]],"overlay":true},{"id":"landsat_233055","name":"Landsat 233055","type":"tms","template":"http://{switch:a,b,c,d}.tile.paulnorman.ca/landsat_233055/{zoom}/{x}/{y}.png","description":"Recent Landsat imagery","scaleExtent":[5,14],"polygon":[[[-60.8550011,6.1765004],[-60.4762612,7.9188291],[-62.161689,8.2778675],[-62.5322549,6.5375488],[-60.8550011,6.1765004]]]},{"id":"landsat_047026","name":"Latest southwest British Columbia Landsat","type":"tms","template":"http://{switch:a,b,c,d}.tile.paulnorman.ca/landsat_047026/{zoom}/{x}/{y}.png","description":"Recent lower-resolution landsat imagery for southwest British Columbia","scaleExtent":[5,13],"polygon":[[[-121.9355512,47.7820648],[-121.5720582,48.6410125],[-121.2015461,49.4846247],[-121.8375516,49.6023246],[-122.4767046,49.7161735],[-123.118912,49.8268824],[-123.760228,49.9335836],[-124.0887706,49.0870469],[-124.4128889,48.2252567],[-123.792772,48.1197334],[-123.1727942,48.0109592],[-122.553553,47.8982299],[-121.9355512,47.7820648]]]},{"id":"ORT10LT","name":"Lithuania - NŽT ORT10LT","type":"tms","template":"http://mapproxy.openmap.lt/ort10lt/g/{zoom}/{x}/{y}.jpeg","scaleExtent":[1,18],"polygon":[[[26.2138385,55.850748],[26.3858298,55.7045315],[26.6303618,55.6806692],[26.6205349,55.5689227],[26.5242191,55.5099228],[26.5541476,55.388833],[26.4399286,55.3479351],[26.7919694,55.3212027],[26.8291304,55.2763488],[26.7434625,55.2539863],[26.6764846,55.158828],[26.4611191,55.1285624],[26.3577434,55.1505399],[26.2296342,55.1073177],[26.2713814,55.0775905],[26.2085126,54.997414],[26.0619117,54.9416094],[25.8578176,54.9276001],[25.7429827,54.8150641],[25.7626083,54.5769013],[25.5319352,54.3418175],[25.6771618,54.3238109],[25.7857293,54.2336242],[25.7858844,54.1550594],[25.5550843,54.1461918],[25.5109462,54.1750267],[25.5896725,54.2285838],[25.5136246,54.3078472],[25.2689287,54.2744706],[25.0705963,54.1336282],[24.9573726,54.1720575],[24.8133801,54.144862],[24.7790172,54.0999054],[24.8712786,54.034904],[24.819568,53.9977218],[24.6845912,53.9621091],[24.697865,54.0171421],[24.6259068,54.0105048],[24.4342619,53.9014424],[24.3520594,53.8967893],[24.2016059,53.9700069],[23.9683341,53.9266977],[23.9130177,53.9696842],[23.7781192,53.8989169],[23.7097655,53.9394502],[23.5370435,53.9430702],[23.4822428,53.9893848],[23.5273356,54.0473482],[23.4858579,54.1532339],[23.3867851,54.224838],[23.0421216,54.3159745],[23.0102115,54.3827959],[22.8546899,54.4104029],[22.7919963,54.3633227],[22.7023421,54.4528985],[22.6838586,54.585972],[22.7489713,54.6319792],[22.7429727,54.7268221],[22.8866837,54.8135001],[22.8204005,54.9119829],[22.6424041,54.9713362],[22.5892361,55.070243],[22.080597,55.0244812],[22.0324081,55.084098],[21.9130671,55.0816838],[21.6491949,55.1808113],[21.5015124,55.1868198],[21.3843708,55.2936996],[21.2709829,55.2450059],[21.0983616,55.2563884],[20.9421741,55.282453],[21.0863466,55.5618266],[21.0399547,55.8363584],[21.0640261,56.0699542],[21.2047804,56.0811668],[21.2307958,56.1623302],[21.5021038,56.2954952],[21.7235874,56.3138211],[21.8356623,56.37162],[21.9695397,56.3766515],[22.0153001,56.4242811],[22.4372717,56.406405],[22.6800028,56.3515884],[22.9191739,56.3790184],[22.9466759,56.4146477],[23.0932498,56.3046383],[23.1703443,56.3667721],[23.3064522,56.3830535],[23.5571715,56.3338187],[23.7647953,56.3733238],[23.7666897,56.3238079],[24.0189971,56.3297615],[24.1214631,56.2488984],[24.2857421,56.3006367],[24.4541496,56.2581579],[24.5794651,56.2882389],[24.6284061,56.3753322],[24.9023767,56.4805317],[25.1277405,56.2059091],[25.5771398,56.182414],[25.6731232,56.1493667],[26.2138385,55.850748]]],"terms_url":"http://www.geoportal.lt","terms_text":"NŽT ORT10LT"},{"id":"mapbox_locator_overlay","name":"Locator Overlay","type":"tms","template":"http://{switch:a,b,c}.tiles.mapbox.com/v4/openstreetmap.map-inh76ba2/{zoom}/{x}/{y}.png?access_token=pk.eyJ1Ijoib3BlbnN0cmVldG1hcCIsImEiOiJncjlmd0t3In0.DmZsIeOW-3x-C5eX-wAqTw","description":"Shows major features to help orient you.","scaleExtent":[0,16],"overzoom":false,"terms_url":"http://www.mapbox.com/about/maps/","terms_text":"Terms & Feedback","default":true,"overlay":true},{"id":"NSW_LPI_BaseMap","name":"LPI NSW Base Map","type":"tms","template":"http://maps.six.nsw.gov.au/arcgis/rest/services/public/NSW_Base_Map/MapServer/tile/{zoom}/{y}/{x}","scaleExtent":[0,19],"polygon":[[[140.9948644,-28.952966],[148.9611382,-28.8997729],[148.9870097,-28.4862285],[151.013609,-28.4786485],[151.1084711,-28.7032909],[151.8759917,-28.683118],[151.9334839,-28.4078753],[152.25544,-28.2332683],[153.0660798,-28.2104723],[153.1408196,-28.1090981],[153.4735137,-28.1164808],[153.3576523,-27.693606],[159.4938303,-27.699252],[159.4856997,-37.8474137],[149.5256879,-37.8281502],[149.9159578,-37.4869999],[148.0485886,-36.8131741],[147.9680996,-36.1567945],[146.7147701,-36.2866613],[145.3004625,-36.1567945],[144.5300673,-36.1475101],[142.8397973,-35.0254303],[142.356863,-34.7802471],[141.9774146,-34.4016159],[140.9950258,-34.1371824],[140.9948644,-28.952966]]],"terms_url":"http://spatialservices.finance.nsw.gov.au/mapping_and_imagery/lpi_web_services","terms_text":"© Land and Property Information 2016"},{"id":"NSW_LPI_Imagery","name":"LPI NSW Imagery","type":"tms","template":"http://maps.six.nsw.gov.au/arcgis/rest/services/public/NSW_Imagery/MapServer/tile/{zoom}/{y}/{x}","scaleExtent":[0,21],"polygon":[[[140.9868688,-28.9887829],[148.9951472,-28.9727491],[148.9966717,-28.4915066],[151.0029027,-28.4930697],[151.0029027,-28.7261663],[151.4915093,-28.7323921],[151.4918687,-28.7155337],[151.9228213,-28.719635],[151.9251607,-28.4897139],[151.9955886,-28.4898718],[151.9989947,-28.1192742],[152.4967606,-28.122091],[152.4968241,-28.1146398],[153.0044563,-28.1154389],[153.0044563,-28.120397],[153.5038629,-28.119345],[153.5039264,-28.1227063],[153.5919395,-28.1223619],[153.5926582,-28.1776872],[153.6111186,-28.1757867],[153.6113881,-28.1825173],[153.7426846,-28.2162084],[153.7787253,-28.710911],[152.6237954,-32.5877239],[152.3123961,-32.6328837],[151.4141942,-33.5790388],[150.8929925,-35.2648721],[150.4620695,-35.7777256],[150.0156501,-37.5103569],[149.9918121,-37.5126787],[149.519778,-37.5130704],[149.5199577,-37.5216919],[149.4462958,-37.5353701],[149.063344,-37.5357975],[148.9836635,-37.5217631],[148.9816872,-37.5191982],[148.9863847,-37.2584972],[148.4875376,-37.265846],[148.4824774,-37.0092669],[147.994386,-37.014339],[147.988288,-36.5332184],[147.9529707,-36.5260725],[147.9486513,-36.0685992],[147.5034997,-36.0716798],[147.5047701,-36.2651047],[146.4919996,-36.266129],[146.4922536,-36.2565],[145.9929826,-36.2534267],[145.9965866,-36.0188147],[145.9831568,-36.0187058],[145.9624506,-36.0219026],[145.946236,-36.0120936],[145.9454275,-36.0060259],[145.5041534,-36.0013564],[145.5037941,-36.0109125],[145.0072008,-36.0036213],[145.0035404,-36.1520424],[144.4860806,-36.1423149],[144.4874127,-36.0137522],[143.9874676,-36.0024134],[143.9932853,-35.5723753],[143.4971691,-35.5837101],[143.4917967,-35.4065648],[143.4613438,-35.3674934],[143.4585591,-35.3555888],[143.4897755,-35.3396522],[143.4895509,-35.332214],[143.4316994,-35.2570613],[143.2505542,-35.2606556],[143.2438356,-35.0132729],[142.9933305,-35.0177207],[142.9919767,-34.7961882],[142.4971375,-34.8032323],[142.4973172,-34.8007613],[142.4211401,-34.8017571],[142.4209155,-34.7838306],[142.2330892,-34.7859191],[142.2307707,-34.7807542],[142.2269959,-34.5061271],[141.9975302,-34.5083733],[141.9945959,-34.2526687],[141.4982345,-34.2556921],[141.498171,-34.2522794],[140.9945397,-34.2528411],[140.9868688,-28.9887829]]],"terms_url":"http://spatialservices.finance.nsw.gov.au/mapping_and_imagery/lpi_web_services","terms_text":"© Land and Property Information 2016","best":true},{"id":"NSW_LPI_TopographicMap","name":"LPI NSW Topographic Map","type":"tms","template":"http://maps.six.nsw.gov.au/arcgis/rest/services/public/NSW_Topo_Map/MapServer/tile/{zoom}/{y}/{x}","scaleExtent":[0,16],"polygon":[[[140.9988422,-28.9992444],[148.9502438,-28.9993736],[148.9498845,-28.9665265],[148.9998308,-28.9665265],[149.0000917,-28.8165829],[149.1000729,-28.8165829],[149.0997046,-28.7488533],[148.9998504,-28.7497444],[148.9998169,-28.5000304],[151.0000514,-28.5005192],[151.0005904,-28.7325849],[151.0239466,-28.7327424],[151.0241262,-28.7418794],[151.0329297,-28.7418794],[151.033828,-28.7505431],[151.999984,-28.7495314],[151.999984,-28.7164478],[152.0334014,-28.7166053],[152.0332217,-28.683196],[152.0000739,-28.6833537],[151.9998769,-28.6416273],[151.9829886,-28.6413908],[151.9831683,-28.624912],[151.9331321,-28.6247543],[151.9334122,-28.500071],[151.9998875,-28.5002289],[151.9998556,-28.3749591],[152.2499739,-28.3750718],[152.2499356,-28.2500066],[152.9997192,-28.2498563],[152.9998989,-28.2832447],[153.1165002,-28.2834029],[153.11659,-28.2498563],[153.1666262,-28.2500146],[153.166716,-28.2331582],[153.2499898,-28.2332373],[153.2500265,-28.1249689],[153.6249628,-28.1250833],[153.6248398,-28.4999134],[153.7497955,-28.4999924],[153.7495877,-28.7497976],[153.6248117,-28.7501127],[153.6249745,-28.9999333],[153.4997672,-29.0000612],[153.4998417,-29.4995077],[153.3747962,-29.500055],[153.3754111,-29.8750302],[153.4999113,-29.8751403],[153.4999113,-30.0000922],[153.2498947,-29.9997621],[153.250025,-30.1917704],[153.2748185,-30.1916151],[153.2748185,-30.2168467],[153.2166077,-30.2166139],[153.2166077,-30.250065],[153.250025,-30.250065],[153.2497502,-30.3751935],[153.1243608,-30.3749743],[153.1246457,-30.6250359],[153.0331676,-30.6250482],[153.0333884,-30.8750837],[153.1249214,-30.8750291],[153.1249344,-31.1250505],[153.0082433,-31.1249736],[153.0082914,-31.2499759],[153.0000019,-31.250003],[152.9999392,-31.6249919],[152.8749386,-31.6250491],[152.8749572,-31.749954],[152.7832899,-31.7500034],[152.7831966,-31.8748579],[152.749914,-31.8750105],[152.7500397,-32.0000207],[152.6249044,-31.9999446],[152.6249078,-32.5000047],[152.4999757,-32.4999569],[152.5000336,-32.5666443],[152.4166699,-32.5663415],[152.4167598,-32.6249954],[152.3498477,-32.624991],[152.3498477,-32.6332294],[152.2830786,-32.6332218],[152.2832583,-32.6249755],[152.2494816,-32.6249755],[152.2498101,-32.874906],[151.8745693,-32.8750443],[151.8748535,-33.0000091],[151.7497706,-33.0001533],[151.7504669,-33.2500398],[151.6252418,-33.2497393],[151.6250828,-33.3751621],[151.499585,-33.3751442],[151.5003127,-33.6249385],[151.3741466,-33.6243658],[151.3727902,-34.001962],[151.2477819,-34.0011194],[151.2477819,-34.2493114],[150.9957327,-34.2501515],[151.0008143,-34.62483],[150.8717407,-34.6265026],[150.872757,-35.1242738],[150.7670589,-35.1234425],[150.7690916,-35.2463774],[150.6257894,-35.2496974],[150.6280314,-35.3751485],[150.4999742,-35.3751485],[150.4959088,-35.6275034],[150.3719169,-35.6250251],[150.3749658,-35.7537957],[150.2672351,-35.7513213],[150.2652024,-35.8741232],[150.2479249,-35.870829],[150.2458922,-36.374885],[150.1229166,-36.374885],[150.1259656,-36.6224345],[150.0253491,-36.6240658],[150.0283981,-36.7471337],[149.9928266,-36.7495768],[150.0040062,-37.1224477],[150.0588879,-37.1273097],[150.0568553,-37.37809],[149.9979083,-37.3732441],[149.9999409,-37.4830073],[149.987745,-37.4846202],[149.9857123,-37.5080043],[148.0684571,-36.80624],[147.9930603,-36.1379955],[147.8148345,-36.0055567],[147.3893924,-36.0113701],[147.3822059,-36.1310306],[146.9972549,-36.1275479],[146.9886311,-36.2528271],[146.4956356,-36.2447132],[146.5042595,-36.126387],[145.0011817,-36.0079505],[145.0154103,-36.2542074],[144.5072465,-36.2476506],[144.4991158,-36.0211037],[143.9965422,-35.9810531],[143.3382568,-35.2331794],[142.4097581,-34.7669434],[142.0361436,-34.3758837],[140.9965216,-34.1385805],[140.9988422,-28.9992444]]],"terms_url":"http://spatialservices.finance.nsw.gov.au/mapping_and_imagery/lpi_web_services","terms_text":"© Land and Property Information 2016"},{"id":"lu.geoportail.opendata.basemap","name":"Luxembourg Geoportail Basemap","type":"tms","template":"https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/basemap/GLOBAL_WEBMERCATOR_4_V3/{zoom}/{x}/{y}.png","scaleExtent":[0,20],"polygon":[[[5.961753,50.17631],[6.026268,50.18496],[6.033182,50.16395],[6.060695,50.15536],[6.07668,50.15913],[6.078237,50.17255],[6.101762,50.17199],[6.122501,50.16437],[6.120101,50.15594],[6.127695,50.14993],[6.113228,50.13739],[6.123691,50.13719],[6.140929,50.1305],[6.135554,50.11899],[6.138082,50.10263],[6.131085,50.09964],[6.135473,50.09119],[6.121939,50.09059],[6.126335,50.07817],[6.131858,50.07348],[6.121171,50.064],[6.114444,50.06139],[6.115631,50.05817],[6.123611,50.06323],[6.136608,50.04178],[6.130343,50.02975],[6.148207,50.02307],[6.13868,50.01572],[6.135938,50.01485],[6.131384,50.01905],[6.130243,50.01819],[6.139343,50.01116],[6.151702,50.01058],[6.145464,49.99689],[6.139657,49.9994],[6.138524,49.99829],[6.142178,49.99535],[6.150227,49.99518],[6.156247,49.98867],[6.173045,49.98589],[6.17348,49.98344],[6.170353,49.98376],[6.165487,49.97115],[6.171512,49.96298],[6.176298,49.962],[6.179954,49.95386],[6.183393,49.9548],[6.179829,49.96307],[6.183312,49.9686],[6.192774,49.97158],[6.199783,49.95352],[6.207066,49.95672],[6.212689,49.9514],[6.225023,49.95039],[6.22044,49.94369],[6.228241,49.93726],[6.22635,49.92766],[6.219133,49.92354],[6.229862,49.92125],[6.236032,49.91355],[6.231867,49.91064],[6.227694,49.91062],[6.232286,49.9072],[6.23381,49.90028],[6.246919,49.89535],[6.257809,49.88724],[6.263008,49.88101],[6.276455,49.87725],[6.281126,49.87957],[6.291661,49.87548],[6.297699,49.86673],[6.309889,49.87107],[6.315324,49.8673],[6.314651,49.86057],[6.323611,49.85188],[6.321577,49.8409],[6.327406,49.83673],[6.336561,49.83998],[6.339366,49.8507],[6.364651,49.85164],[6.402203,49.82098],[6.426434,49.81629],[6.428071,49.81186],[6.43097,49.81129],[6.441608,49.81547],[6.443442,49.81233],[6.45366,49.81275],[6.464538,49.81975],[6.47057,49.82385],[6.496805,49.81277],[6.50669,49.80993],[6.511554,49.80238],[6.51485,49.80513],[6.519604,49.81446],[6.529808,49.81048],[6.532249,49.80686],[6.530829,49.80116],[6.506225,49.78899],[6.519171,49.78344],[6.511055,49.77422],[6.520563,49.76818],[6.520516,49.76134],[6.503734,49.75086],[6.502627,49.73298],[6.507266,49.72938],[6.518092,49.7242],[6.516417,49.72129],[6.511763,49.72016],[6.504791,49.725],[6.498913,49.72639],[6.495576,49.72443],[6.507122,49.71655],[6.507884,49.71215],[6.504598,49.71227],[6.427139,49.66237],[6.439899,49.66025],[6.442511,49.65591],[6.421781,49.61809],[6.398978,49.60094],[6.379408,49.59526],[6.375507,49.58809],[6.384426,49.5801],[6.381188,49.57509],[6.369093,49.5783],[6.357913,49.57166],[6.384902,49.55817],[6.380095,49.54856],[6.358555,49.53296],[6.359322,49.52481],[6.370763,49.50545],[6.370562,49.45732],[6.333403,49.46493],[6.321894,49.47244],[6.295034,49.47928],[6.287889,49.48379],[6.271912,49.49995],[6.241327,49.50693],[6.196692,49.50331],[6.173373,49.50577],[6.160858,49.50085],[6.167099,49.49006],[6.140179,49.48525],[6.129367,49.48803],[6.127247,49.47081],[6.101403,49.46726],[6.104826,49.45076],[6.081667,49.45417],[6.077222,49.46139],[6.059167,49.46306],[6.052222,49.46028],[6.044213,49.44553],[6.025294,49.44703],[6.021545,49.45127],[6.01574,49.44885],[5.994123,49.45301],[5.976569,49.44885],[5.977725,49.45955],[5.972317,49.46087],[5.968912,49.48202],[5.9616,49.49026],[5.915781,49.49835],[5.890334,49.4948],[5.863321,49.50006],[5.84897,49.50826],[5.84828,49.51397],[5.83641,49.51817],[5.831868,49.52639],[5.84308,49.53081],[5.835622,49.54114],[5.816251,49.53325],[5.805201,49.54272],[5.859432,49.57158],[5.868663,49.587],[5.862888,49.58525],[5.851102,49.58379],[5.847116,49.58961],[5.845652,49.5981],[5.869401,49.6106],[5.881819,49.63815],[5.899978,49.63907],[5.899339,49.66239],[5.856561,49.67628],[5.856283,49.68211],[5.875703,49.71118],[5.864811,49.72331],[5.843249,49.71822],[5.82191,49.72128],[5.824894,49.73767],[5.820728,49.74878],[5.786264,49.79079],[5.765172,49.78961],[5.750937,49.79094],[5.741591,49.82126],[5.745814,49.82435],[5.737197,49.83353],[5.740531,49.84142],[5.747012,49.84048],[5.746237,49.84783],[5.753989,49.84878],[5.740663,49.85152],[5.752288,49.85922],[5.749545,49.87554],[5.775668,49.87438],[5.775053,49.88057],[5.734598,49.89341],[5.733033,49.90285],[5.757834,49.91737],[5.760393,49.93252],[5.770728,49.93711],[5.768783,49.94239],[5.768802,49.96104],[5.786724,49.96816],[5.80524,49.96677],[5.806521,49.97321],[5.831293,49.97995],[5.834616,49.98656],[5.818057,49.99936],[5.815606,50.01437],[5.847923,50.02809],[5.861889,50.04581],[5.850872,50.0563],[5.857809,50.07186],[5.880997,50.08069],[5.891965,50.12041],[5.952856,50.13384],[5.961753,50.17631]]],"terms_url":"https://data.public.lu/en/datasets/carte-de-base-webservices-wms-et-wmts/","terms_text":"Administration du Cadastre et de la Topographie"},{"id":"lu.geoportail.opendata.cadastre","name":"Luxembourg Geoportail Cadastre","type":"tms","template":"https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/cadastre/GLOBAL_WEBMERCATOR_4_V3/{zoom}/{x}/{y}.png","scaleExtent":[0,20],"polygon":[[[5.961753,50.17631],[6.026268,50.18496],[6.033182,50.16395],[6.060695,50.15536],[6.07668,50.15913],[6.078237,50.17255],[6.101762,50.17199],[6.122501,50.16437],[6.120101,50.15594],[6.127695,50.14993],[6.113228,50.13739],[6.123691,50.13719],[6.140929,50.1305],[6.135554,50.11899],[6.138082,50.10263],[6.131085,50.09964],[6.135473,50.09119],[6.121939,50.09059],[6.126335,50.07817],[6.131858,50.07348],[6.121171,50.064],[6.114444,50.06139],[6.115631,50.05817],[6.123611,50.06323],[6.136608,50.04178],[6.130343,50.02975],[6.148207,50.02307],[6.13868,50.01572],[6.135938,50.01485],[6.131384,50.01905],[6.130243,50.01819],[6.139343,50.01116],[6.151702,50.01058],[6.145464,49.99689],[6.139657,49.9994],[6.138524,49.99829],[6.142178,49.99535],[6.150227,49.99518],[6.156247,49.98867],[6.173045,49.98589],[6.17348,49.98344],[6.170353,49.98376],[6.165487,49.97115],[6.171512,49.96298],[6.176298,49.962],[6.179954,49.95386],[6.183393,49.9548],[6.179829,49.96307],[6.183312,49.9686],[6.192774,49.97158],[6.199783,49.95352],[6.207066,49.95672],[6.212689,49.9514],[6.225023,49.95039],[6.22044,49.94369],[6.228241,49.93726],[6.22635,49.92766],[6.219133,49.92354],[6.229862,49.92125],[6.236032,49.91355],[6.231867,49.91064],[6.227694,49.91062],[6.232286,49.9072],[6.23381,49.90028],[6.246919,49.89535],[6.257809,49.88724],[6.263008,49.88101],[6.276455,49.87725],[6.281126,49.87957],[6.291661,49.87548],[6.297699,49.86673],[6.309889,49.87107],[6.315324,49.8673],[6.314651,49.86057],[6.323611,49.85188],[6.321577,49.8409],[6.327406,49.83673],[6.336561,49.83998],[6.339366,49.8507],[6.364651,49.85164],[6.402203,49.82098],[6.426434,49.81629],[6.428071,49.81186],[6.43097,49.81129],[6.441608,49.81547],[6.443442,49.81233],[6.45366,49.81275],[6.464538,49.81975],[6.47057,49.82385],[6.496805,49.81277],[6.50669,49.80993],[6.511554,49.80238],[6.51485,49.80513],[6.519604,49.81446],[6.529808,49.81048],[6.532249,49.80686],[6.530829,49.80116],[6.506225,49.78899],[6.519171,49.78344],[6.511055,49.77422],[6.520563,49.76818],[6.520516,49.76134],[6.503734,49.75086],[6.502627,49.73298],[6.507266,49.72938],[6.518092,49.7242],[6.516417,49.72129],[6.511763,49.72016],[6.504791,49.725],[6.498913,49.72639],[6.495576,49.72443],[6.507122,49.71655],[6.507884,49.71215],[6.504598,49.71227],[6.427139,49.66237],[6.439899,49.66025],[6.442511,49.65591],[6.421781,49.61809],[6.398978,49.60094],[6.379408,49.59526],[6.375507,49.58809],[6.384426,49.5801],[6.381188,49.57509],[6.369093,49.5783],[6.357913,49.57166],[6.384902,49.55817],[6.380095,49.54856],[6.358555,49.53296],[6.359322,49.52481],[6.370763,49.50545],[6.370562,49.45732],[6.333403,49.46493],[6.321894,49.47244],[6.295034,49.47928],[6.287889,49.48379],[6.271912,49.49995],[6.241327,49.50693],[6.196692,49.50331],[6.173373,49.50577],[6.160858,49.50085],[6.167099,49.49006],[6.140179,49.48525],[6.129367,49.48803],[6.127247,49.47081],[6.101403,49.46726],[6.104826,49.45076],[6.081667,49.45417],[6.077222,49.46139],[6.059167,49.46306],[6.052222,49.46028],[6.044213,49.44553],[6.025294,49.44703],[6.021545,49.45127],[6.01574,49.44885],[5.994123,49.45301],[5.976569,49.44885],[5.977725,49.45955],[5.972317,49.46087],[5.968912,49.48202],[5.9616,49.49026],[5.915781,49.49835],[5.890334,49.4948],[5.863321,49.50006],[5.84897,49.50826],[5.84828,49.51397],[5.83641,49.51817],[5.831868,49.52639],[5.84308,49.53081],[5.835622,49.54114],[5.816251,49.53325],[5.805201,49.54272],[5.859432,49.57158],[5.868663,49.587],[5.862888,49.58525],[5.851102,49.58379],[5.847116,49.58961],[5.845652,49.5981],[5.869401,49.6106],[5.881819,49.63815],[5.899978,49.63907],[5.899339,49.66239],[5.856561,49.67628],[5.856283,49.68211],[5.875703,49.71118],[5.864811,49.72331],[5.843249,49.71822],[5.82191,49.72128],[5.824894,49.73767],[5.820728,49.74878],[5.786264,49.79079],[5.765172,49.78961],[5.750937,49.79094],[5.741591,49.82126],[5.745814,49.82435],[5.737197,49.83353],[5.740531,49.84142],[5.747012,49.84048],[5.746237,49.84783],[5.753989,49.84878],[5.740663,49.85152],[5.752288,49.85922],[5.749545,49.87554],[5.775668,49.87438],[5.775053,49.88057],[5.734598,49.89341],[5.733033,49.90285],[5.757834,49.91737],[5.760393,49.93252],[5.770728,49.93711],[5.768783,49.94239],[5.768802,49.96104],[5.786724,49.96816],[5.80524,49.96677],[5.806521,49.97321],[5.831293,49.97995],[5.834616,49.98656],[5.818057,49.99936],[5.815606,50.01437],[5.847923,50.02809],[5.861889,50.04581],[5.850872,50.0563],[5.857809,50.07186],[5.880997,50.08069],[5.891965,50.12041],[5.952856,50.13384],[5.961753,50.17631]]],"terms_url":"https://data.public.lu/en/datasets/plan-cadastral-numerise-pcn-webservices-wms-et-wmts/","terms_text":"Administration du Cadastre et de la Topographie"},{"id":"lu.geoportail.opendata.ortho2010","name":"Luxembourg Geoportail Ortho 2010","type":"tms","template":"https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/ortho_2010/GLOBAL_WEBMERCATOR_4_V3/{zoom}/{x}/{y}.jpeg","scaleExtent":[0,20],"polygon":[[[5.961753,50.17631],[6.026268,50.18496],[6.033182,50.16395],[6.060695,50.15536],[6.07668,50.15913],[6.078237,50.17255],[6.101762,50.17199],[6.122501,50.16437],[6.120101,50.15594],[6.127695,50.14993],[6.113228,50.13739],[6.123691,50.13719],[6.140929,50.1305],[6.135554,50.11899],[6.138082,50.10263],[6.131085,50.09964],[6.135473,50.09119],[6.121939,50.09059],[6.126335,50.07817],[6.131858,50.07348],[6.121171,50.064],[6.114444,50.06139],[6.115631,50.05817],[6.123611,50.06323],[6.136608,50.04178],[6.130343,50.02975],[6.148207,50.02307],[6.13868,50.01572],[6.135938,50.01485],[6.131384,50.01905],[6.130243,50.01819],[6.139343,50.01116],[6.151702,50.01058],[6.145464,49.99689],[6.139657,49.9994],[6.138524,49.99829],[6.142178,49.99535],[6.150227,49.99518],[6.156247,49.98867],[6.173045,49.98589],[6.17348,49.98344],[6.170353,49.98376],[6.165487,49.97115],[6.171512,49.96298],[6.176298,49.962],[6.179954,49.95386],[6.183393,49.9548],[6.179829,49.96307],[6.183312,49.9686],[6.192774,49.97158],[6.199783,49.95352],[6.207066,49.95672],[6.212689,49.9514],[6.225023,49.95039],[6.22044,49.94369],[6.228241,49.93726],[6.22635,49.92766],[6.219133,49.92354],[6.229862,49.92125],[6.236032,49.91355],[6.231867,49.91064],[6.227694,49.91062],[6.232286,49.9072],[6.23381,49.90028],[6.246919,49.89535],[6.257809,49.88724],[6.263008,49.88101],[6.276455,49.87725],[6.281126,49.87957],[6.291661,49.87548],[6.297699,49.86673],[6.309889,49.87107],[6.315324,49.8673],[6.314651,49.86057],[6.323611,49.85188],[6.321577,49.8409],[6.327406,49.83673],[6.336561,49.83998],[6.339366,49.8507],[6.364651,49.85164],[6.402203,49.82098],[6.426434,49.81629],[6.428071,49.81186],[6.43097,49.81129],[6.441608,49.81547],[6.443442,49.81233],[6.45366,49.81275],[6.464538,49.81975],[6.47057,49.82385],[6.496805,49.81277],[6.50669,49.80993],[6.511554,49.80238],[6.51485,49.80513],[6.519604,49.81446],[6.529808,49.81048],[6.532249,49.80686],[6.530829,49.80116],[6.506225,49.78899],[6.519171,49.78344],[6.511055,49.77422],[6.520563,49.76818],[6.520516,49.76134],[6.503734,49.75086],[6.502627,49.73298],[6.507266,49.72938],[6.518092,49.7242],[6.516417,49.72129],[6.511763,49.72016],[6.504791,49.725],[6.498913,49.72639],[6.495576,49.72443],[6.507122,49.71655],[6.507884,49.71215],[6.504598,49.71227],[6.427139,49.66237],[6.439899,49.66025],[6.442511,49.65591],[6.421781,49.61809],[6.398978,49.60094],[6.379408,49.59526],[6.375507,49.58809],[6.384426,49.5801],[6.381188,49.57509],[6.369093,49.5783],[6.357913,49.57166],[6.384902,49.55817],[6.380095,49.54856],[6.358555,49.53296],[6.359322,49.52481],[6.370763,49.50545],[6.370562,49.45732],[6.333403,49.46493],[6.321894,49.47244],[6.295034,49.47928],[6.287889,49.48379],[6.271912,49.49995],[6.241327,49.50693],[6.196692,49.50331],[6.173373,49.50577],[6.160858,49.50085],[6.167099,49.49006],[6.140179,49.48525],[6.129367,49.48803],[6.127247,49.47081],[6.101403,49.46726],[6.104826,49.45076],[6.081667,49.45417],[6.077222,49.46139],[6.059167,49.46306],[6.052222,49.46028],[6.044213,49.44553],[6.025294,49.44703],[6.021545,49.45127],[6.01574,49.44885],[5.994123,49.45301],[5.976569,49.44885],[5.977725,49.45955],[5.972317,49.46087],[5.968912,49.48202],[5.9616,49.49026],[5.915781,49.49835],[5.890334,49.4948],[5.863321,49.50006],[5.84897,49.50826],[5.84828,49.51397],[5.83641,49.51817],[5.831868,49.52639],[5.84308,49.53081],[5.835622,49.54114],[5.816251,49.53325],[5.805201,49.54272],[5.859432,49.57158],[5.868663,49.587],[5.862888,49.58525],[5.851102,49.58379],[5.847116,49.58961],[5.845652,49.5981],[5.869401,49.6106],[5.881819,49.63815],[5.899978,49.63907],[5.899339,49.66239],[5.856561,49.67628],[5.856283,49.68211],[5.875703,49.71118],[5.864811,49.72331],[5.843249,49.71822],[5.82191,49.72128],[5.824894,49.73767],[5.820728,49.74878],[5.786264,49.79079],[5.765172,49.78961],[5.750937,49.79094],[5.741591,49.82126],[5.745814,49.82435],[5.737197,49.83353],[5.740531,49.84142],[5.747012,49.84048],[5.746237,49.84783],[5.753989,49.84878],[5.740663,49.85152],[5.752288,49.85922],[5.749545,49.87554],[5.775668,49.87438],[5.775053,49.88057],[5.734598,49.89341],[5.733033,49.90285],[5.757834,49.91737],[5.760393,49.93252],[5.770728,49.93711],[5.768783,49.94239],[5.768802,49.96104],[5.786724,49.96816],[5.80524,49.96677],[5.806521,49.97321],[5.831293,49.97995],[5.834616,49.98656],[5.818057,49.99936],[5.815606,50.01437],[5.847923,50.02809],[5.861889,50.04581],[5.850872,50.0563],[5.857809,50.07186],[5.880997,50.08069],[5.891965,50.12041],[5.952856,50.13384],[5.961753,50.17631]]],"terms_url":"https://data.public.lu/en/datasets/bd-l-ortho-webservices-wms-et-wmts","terms_text":"Administration du Cadastre et de la Topographie","best":true},{"id":"lu.geoportail.opendata.ortho2013","name":"Luxembourg Geoportail Ortho 2013","type":"tms","template":"https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/ortho_2013/GLOBAL_WEBMERCATOR_4_V3/{zoom}/{x}/{y}.jpeg","scaleExtent":[0,20],"polygon":[[[5.961753,50.17631],[6.026268,50.18496],[6.033182,50.16395],[6.060695,50.15536],[6.07668,50.15913],[6.078237,50.17255],[6.101762,50.17199],[6.122501,50.16437],[6.120101,50.15594],[6.127695,50.14993],[6.113228,50.13739],[6.123691,50.13719],[6.140929,50.1305],[6.135554,50.11899],[6.138082,50.10263],[6.131085,50.09964],[6.135473,50.09119],[6.121939,50.09059],[6.126335,50.07817],[6.131858,50.07348],[6.121171,50.064],[6.114444,50.06139],[6.115631,50.05817],[6.123611,50.06323],[6.136608,50.04178],[6.130343,50.02975],[6.148207,50.02307],[6.13868,50.01572],[6.135938,50.01485],[6.131384,50.01905],[6.130243,50.01819],[6.139343,50.01116],[6.151702,50.01058],[6.145464,49.99689],[6.139657,49.9994],[6.138524,49.99829],[6.142178,49.99535],[6.150227,49.99518],[6.156247,49.98867],[6.173045,49.98589],[6.17348,49.98344],[6.170353,49.98376],[6.165487,49.97115],[6.171512,49.96298],[6.176298,49.962],[6.179954,49.95386],[6.183393,49.9548],[6.179829,49.96307],[6.183312,49.9686],[6.192774,49.97158],[6.199783,49.95352],[6.207066,49.95672],[6.212689,49.9514],[6.225023,49.95039],[6.22044,49.94369],[6.228241,49.93726],[6.22635,49.92766],[6.219133,49.92354],[6.229862,49.92125],[6.236032,49.91355],[6.231867,49.91064],[6.227694,49.91062],[6.232286,49.9072],[6.23381,49.90028],[6.246919,49.89535],[6.257809,49.88724],[6.263008,49.88101],[6.276455,49.87725],[6.281126,49.87957],[6.291661,49.87548],[6.297699,49.86673],[6.309889,49.87107],[6.315324,49.8673],[6.314651,49.86057],[6.323611,49.85188],[6.321577,49.8409],[6.327406,49.83673],[6.336561,49.83998],[6.339366,49.8507],[6.364651,49.85164],[6.402203,49.82098],[6.426434,49.81629],[6.428071,49.81186],[6.43097,49.81129],[6.441608,49.81547],[6.443442,49.81233],[6.45366,49.81275],[6.464538,49.81975],[6.47057,49.82385],[6.496805,49.81277],[6.50669,49.80993],[6.511554,49.80238],[6.51485,49.80513],[6.519604,49.81446],[6.529808,49.81048],[6.532249,49.80686],[6.530829,49.80116],[6.506225,49.78899],[6.519171,49.78344],[6.511055,49.77422],[6.520563,49.76818],[6.520516,49.76134],[6.503734,49.75086],[6.502627,49.73298],[6.507266,49.72938],[6.518092,49.7242],[6.516417,49.72129],[6.511763,49.72016],[6.504791,49.725],[6.498913,49.72639],[6.495576,49.72443],[6.507122,49.71655],[6.507884,49.71215],[6.504598,49.71227],[6.427139,49.66237],[6.439899,49.66025],[6.442511,49.65591],[6.421781,49.61809],[6.398978,49.60094],[6.379408,49.59526],[6.375507,49.58809],[6.384426,49.5801],[6.381188,49.57509],[6.369093,49.5783],[6.357913,49.57166],[6.384902,49.55817],[6.380095,49.54856],[6.358555,49.53296],[6.359322,49.52481],[6.370763,49.50545],[6.370562,49.45732],[6.333403,49.46493],[6.321894,49.47244],[6.295034,49.47928],[6.287889,49.48379],[6.271912,49.49995],[6.241327,49.50693],[6.196692,49.50331],[6.173373,49.50577],[6.160858,49.50085],[6.167099,49.49006],[6.140179,49.48525],[6.129367,49.48803],[6.127247,49.47081],[6.101403,49.46726],[6.104826,49.45076],[6.081667,49.45417],[6.077222,49.46139],[6.059167,49.46306],[6.052222,49.46028],[6.044213,49.44553],[6.025294,49.44703],[6.021545,49.45127],[6.01574,49.44885],[5.994123,49.45301],[5.976569,49.44885],[5.977725,49.45955],[5.972317,49.46087],[5.968912,49.48202],[5.9616,49.49026],[5.915781,49.49835],[5.890334,49.4948],[5.863321,49.50006],[5.84897,49.50826],[5.84828,49.51397],[5.83641,49.51817],[5.831868,49.52639],[5.84308,49.53081],[5.835622,49.54114],[5.816251,49.53325],[5.805201,49.54272],[5.859432,49.57158],[5.868663,49.587],[5.862888,49.58525],[5.851102,49.58379],[5.847116,49.58961],[5.845652,49.5981],[5.869401,49.6106],[5.881819,49.63815],[5.899978,49.63907],[5.899339,49.66239],[5.856561,49.67628],[5.856283,49.68211],[5.875703,49.71118],[5.864811,49.72331],[5.843249,49.71822],[5.82191,49.72128],[5.824894,49.73767],[5.820728,49.74878],[5.786264,49.79079],[5.765172,49.78961],[5.750937,49.79094],[5.741591,49.82126],[5.745814,49.82435],[5.737197,49.83353],[5.740531,49.84142],[5.747012,49.84048],[5.746237,49.84783],[5.753989,49.84878],[5.740663,49.85152],[5.752288,49.85922],[5.749545,49.87554],[5.775668,49.87438],[5.775053,49.88057],[5.734598,49.89341],[5.733033,49.90285],[5.757834,49.91737],[5.760393,49.93252],[5.770728,49.93711],[5.768783,49.94239],[5.768802,49.96104],[5.786724,49.96816],[5.80524,49.96677],[5.806521,49.97321],[5.831293,49.97995],[5.834616,49.98656],[5.818057,49.99936],[5.815606,50.01437],[5.847923,50.02809],[5.861889,50.04581],[5.850872,50.0563],[5.857809,50.07186],[5.880997,50.08069],[5.891965,50.12041],[5.952856,50.13384],[5.961753,50.17631]]],"terms_url":"https://data.public.lu/en/datasets/bd-l-ortho-webservices-wms-et-wmts","terms_text":"Administration du Cadastre et de la Topographie","best":true},{"id":"lu.geoportail.opendata.topo","name":"Luxembourg Geoportail Topographical Map","type":"tms","template":"https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/topo/GLOBAL_WEBMERCATOR_4_V3/{zoom}/{x}/{y}.png","scaleExtent":[0,20],"polygon":[[[5.961753,50.17631],[6.026268,50.18496],[6.033182,50.16395],[6.060695,50.15536],[6.07668,50.15913],[6.078237,50.17255],[6.101762,50.17199],[6.122501,50.16437],[6.120101,50.15594],[6.127695,50.14993],[6.113228,50.13739],[6.123691,50.13719],[6.140929,50.1305],[6.135554,50.11899],[6.138082,50.10263],[6.131085,50.09964],[6.135473,50.09119],[6.121939,50.09059],[6.126335,50.07817],[6.131858,50.07348],[6.121171,50.064],[6.114444,50.06139],[6.115631,50.05817],[6.123611,50.06323],[6.136608,50.04178],[6.130343,50.02975],[6.148207,50.02307],[6.13868,50.01572],[6.135938,50.01485],[6.131384,50.01905],[6.130243,50.01819],[6.139343,50.01116],[6.151702,50.01058],[6.145464,49.99689],[6.139657,49.9994],[6.138524,49.99829],[6.142178,49.99535],[6.150227,49.99518],[6.156247,49.98867],[6.173045,49.98589],[6.17348,49.98344],[6.170353,49.98376],[6.165487,49.97115],[6.171512,49.96298],[6.176298,49.962],[6.179954,49.95386],[6.183393,49.9548],[6.179829,49.96307],[6.183312,49.9686],[6.192774,49.97158],[6.199783,49.95352],[6.207066,49.95672],[6.212689,49.9514],[6.225023,49.95039],[6.22044,49.94369],[6.228241,49.93726],[6.22635,49.92766],[6.219133,49.92354],[6.229862,49.92125],[6.236032,49.91355],[6.231867,49.91064],[6.227694,49.91062],[6.232286,49.9072],[6.23381,49.90028],[6.246919,49.89535],[6.257809,49.88724],[6.263008,49.88101],[6.276455,49.87725],[6.281126,49.87957],[6.291661,49.87548],[6.297699,49.86673],[6.309889,49.87107],[6.315324,49.8673],[6.314651,49.86057],[6.323611,49.85188],[6.321577,49.8409],[6.327406,49.83673],[6.336561,49.83998],[6.339366,49.8507],[6.364651,49.85164],[6.402203,49.82098],[6.426434,49.81629],[6.428071,49.81186],[6.43097,49.81129],[6.441608,49.81547],[6.443442,49.81233],[6.45366,49.81275],[6.464538,49.81975],[6.47057,49.82385],[6.496805,49.81277],[6.50669,49.80993],[6.511554,49.80238],[6.51485,49.80513],[6.519604,49.81446],[6.529808,49.81048],[6.532249,49.80686],[6.530829,49.80116],[6.506225,49.78899],[6.519171,49.78344],[6.511055,49.77422],[6.520563,49.76818],[6.520516,49.76134],[6.503734,49.75086],[6.502627,49.73298],[6.507266,49.72938],[6.518092,49.7242],[6.516417,49.72129],[6.511763,49.72016],[6.504791,49.725],[6.498913,49.72639],[6.495576,49.72443],[6.507122,49.71655],[6.507884,49.71215],[6.504598,49.71227],[6.427139,49.66237],[6.439899,49.66025],[6.442511,49.65591],[6.421781,49.61809],[6.398978,49.60094],[6.379408,49.59526],[6.375507,49.58809],[6.384426,49.5801],[6.381188,49.57509],[6.369093,49.5783],[6.357913,49.57166],[6.384902,49.55817],[6.380095,49.54856],[6.358555,49.53296],[6.359322,49.52481],[6.370763,49.50545],[6.370562,49.45732],[6.333403,49.46493],[6.321894,49.47244],[6.295034,49.47928],[6.287889,49.48379],[6.271912,49.49995],[6.241327,49.50693],[6.196692,49.50331],[6.173373,49.50577],[6.160858,49.50085],[6.167099,49.49006],[6.140179,49.48525],[6.129367,49.48803],[6.127247,49.47081],[6.101403,49.46726],[6.104826,49.45076],[6.081667,49.45417],[6.077222,49.46139],[6.059167,49.46306],[6.052222,49.46028],[6.044213,49.44553],[6.025294,49.44703],[6.021545,49.45127],[6.01574,49.44885],[5.994123,49.45301],[5.976569,49.44885],[5.977725,49.45955],[5.972317,49.46087],[5.968912,49.48202],[5.9616,49.49026],[5.915781,49.49835],[5.890334,49.4948],[5.863321,49.50006],[5.84897,49.50826],[5.84828,49.51397],[5.83641,49.51817],[5.831868,49.52639],[5.84308,49.53081],[5.835622,49.54114],[5.816251,49.53325],[5.805201,49.54272],[5.859432,49.57158],[5.868663,49.587],[5.862888,49.58525],[5.851102,49.58379],[5.847116,49.58961],[5.845652,49.5981],[5.869401,49.6106],[5.881819,49.63815],[5.899978,49.63907],[5.899339,49.66239],[5.856561,49.67628],[5.856283,49.68211],[5.875703,49.71118],[5.864811,49.72331],[5.843249,49.71822],[5.82191,49.72128],[5.824894,49.73767],[5.820728,49.74878],[5.786264,49.79079],[5.765172,49.78961],[5.750937,49.79094],[5.741591,49.82126],[5.745814,49.82435],[5.737197,49.83353],[5.740531,49.84142],[5.747012,49.84048],[5.746237,49.84783],[5.753989,49.84878],[5.740663,49.85152],[5.752288,49.85922],[5.749545,49.87554],[5.775668,49.87438],[5.775053,49.88057],[5.734598,49.89341],[5.733033,49.90285],[5.757834,49.91737],[5.760393,49.93252],[5.770728,49.93711],[5.768783,49.94239],[5.768802,49.96104],[5.786724,49.96816],[5.80524,49.96677],[5.806521,49.97321],[5.831293,49.97995],[5.834616,49.98656],[5.818057,49.99936],[5.815606,50.01437],[5.847923,50.02809],[5.861889,50.04581],[5.850872,50.0563],[5.857809,50.07186],[5.880997,50.08069],[5.891965,50.12041],[5.952856,50.13384],[5.961753,50.17631]]],"terms_url":"https://data.public.lu/en/datasets/cartes-topographiques-services-wms-et-wmts/","terms_text":"Administration du Cadastre et de la Topographie"},{"id":"Mapbox","name":"Mapbox Satellite","type":"tms","template":"http://{switch:a,b,c}.tiles.mapbox.com/v4/openstreetmap.map-inh7ifmo/{zoom}/{x}/{y}.png?access_token=pk.eyJ1Ijoib3BlbnN0cmVldG1hcCIsImEiOiJncjlmd0t3In0.DmZsIeOW-3x-C5eX-wAqTw","description":"Satellite and aerial imagery.","scaleExtent":[0,19],"terms_url":"http://www.mapbox.com/about/maps/","terms_text":"Terms & Feedback","default":true},{"id":"geodata.md.gov-MD_SixInchImagery","name":"MD 2014 6 Inch Aerial Imagery","type":"tms","template":"http://whoots.mapwarper.net/tms/{zoom}/{x}/{y}/MD_SixInchImagery/http://geodata.md.gov/imap/services/Imagery/MD_SixInchImagery/MapServer/WmsServer","description":"Six Inch resolution aerial imagery for the State of Maryland","scaleExtent":[0,20],"polygon":[[[-76.234131,37.920368],[-76.598053,38.158317],[-76.940002,38.270532],[-77.038193,38.413786],[-77.23526,38.33627],[-77.312164,38.410558],[-77.262726,38.566422],[-77.042999,38.713376],[-77.049866,38.793697],[-76.92627,38.892503],[-77.040939,38.984499],[-77.12162,38.925229],[-77.150116,38.955137],[-77.252426,38.975425],[-77.259293,39.024252],[-77.34581,39.054918],[-77.461853,39.070379],[-77.537384,39.139647],[-77.474213,39.224807],[-77.572746,39.304284],[-77.723465,39.328986],[-77.777023,39.463234],[-77.861481,39.516225],[-77.840881,39.608862],[-77.956238,39.59299],[-78.166351,39.695564],[-78.270035,39.621557],[-78.338699,39.640066],[-78.466415,39.523641],[-78.662796,39.540058],[-78.798752,39.606217],[-78.9814,39.446799],[-79.06723,39.476486],[-79.485054,39.199536],[-79.485569,39.72158],[-75.788359,39.721811],[-75.690994,38.460579],[-75.049238,38.458159],[-75.049839,38.402218],[-75.081511,38.323208],[-75.097733,38.309066],[-75.186996,38.097551],[-75.23798,38.022402],[-75.61821,37.989669],[-75.863686,37.909534],[-76.234131,37.920368]]],"terms_url":"http://imap.maryland.gov/Pages/imagery-products.aspx","terms_text":"DoIT, MD iMap, MDP"},{"id":"geodata.md.gov-MD_ColorBasemap","name":"MD Transportation Basemap","type":"tms","template":"http://whoots.mapwarper.net/tms/{zoom}/{x}/{y}/MD_ColorBasemap/http://geodata.md.gov/imap/services/Transportation/MD_ColorBasemap/MapServer/WmsServer","description":"Maryland State Highway Administration road features and additional Maryland focused landmarks","polygon":[[[-76.234131,37.920368],[-76.598053,38.158317],[-76.940002,38.270532],[-77.038193,38.413786],[-77.23526,38.33627],[-77.312164,38.410558],[-77.262726,38.566422],[-77.042999,38.713376],[-77.049866,38.793697],[-76.92627,38.892503],[-77.040939,38.984499],[-77.12162,38.925229],[-77.150116,38.955137],[-77.252426,38.975425],[-77.259293,39.024252],[-77.34581,39.054918],[-77.461853,39.070379],[-77.537384,39.139647],[-77.474213,39.224807],[-77.572746,39.304284],[-77.723465,39.328986],[-77.777023,39.463234],[-77.861481,39.516225],[-77.840881,39.608862],[-77.956238,39.59299],[-78.166351,39.695564],[-78.270035,39.621557],[-78.338699,39.640066],[-78.466415,39.523641],[-78.662796,39.540058],[-78.798752,39.606217],[-78.9814,39.446799],[-79.06723,39.476486],[-79.485054,39.199536],[-79.485569,39.72158],[-75.788359,39.721811],[-75.690994,38.460579],[-75.049238,38.458159],[-75.049839,38.402218],[-75.081511,38.323208],[-75.097733,38.309066],[-75.186996,38.097551],[-75.23798,38.022402],[-75.61821,37.989669],[-75.863686,37.909534],[-76.234131,37.920368]]],"terms_url":"http://imap.maryland.gov/Pages/imagery-products.aspx","terms_text":"DoIT, MD iMap, MDP"},{"id":"New_and_Misaligned_TIGER_Roads-2013","name":"New & Misaligned TIGER Roads","type":"tms","template":"http://{switch:a,b,c}.tiles.mapbox.com/v4/enf.e0b8291e/{zoom}/{x}/{y}.png?access_token=pk.eyJ1Ijoib3BlbnN0cmVldG1hcCIsImEiOiJhNVlHd29ZIn0.ti6wATGDWOmCnCYen-Ip7Q","description":"At zoom level 16+, public domain map data from the US Census. At lower zooms, only changes since 2006 minus changes already incorporated into OpenStreetMap","scaleExtent":[0,22],"polygon":[[[-124.7617886,48.4130148],[-124.6059492,45.90245],[-124.9934269,40.0557614],[-122.5369737,36.8566086],[-119.9775867,33.0064099],[-117.675935,32.4630223],[-114.8612307,32.4799891],[-111.0089311,31.336015],[-108.1992687,31.3260016],[-108.1871123,31.7755116],[-106.5307225,31.7820947],[-106.4842052,31.7464455],[-106.429317,31.7520583],[-106.2868855,31.5613291],[-106.205248,31.446704],[-105.0205259,30.5360988],[-104.5881916,29.6997856],[-103.2518856,28.8908685],[-102.7173632,29.3920567],[-102.1513983,29.7475702],[-101.2552871,29.4810523],[-100.0062436,28.0082173],[-99.2351068,26.4475962],[-98.0109067,25.9928035],[-97.435024,25.8266009],[-96.9555259,25.9821589],[-96.8061741,27.7978168],[-95.5563349,28.5876066],[-93.7405308,29.4742093],[-90.9028456,28.8564513],[-88.0156706,28.9944338],[-88.0162494,30.0038862],[-86.0277506,30.0047454],[-84.0187909,28.9961781],[-81.9971976,25.9826768],[-81.9966618,25.0134917],[-84.0165592,25.0125783],[-84.0160068,24.0052745],[-80.0199985,24.007096],[-79.8901116,26.8550713],[-80.0245309,32.0161282],[-75.4147385,35.0531894],[-74.0211163,39.5727927],[-72.002019,40.9912464],[-69.8797398,40.9920457],[-69.8489304,43.2619916],[-66.9452845,44.7104937],[-67.7596632,47.0990024],[-69.2505131,47.5122328],[-70.4614886,46.2176574],[-71.412273,45.254878],[-72.0222508,45.0059846],[-75.0798841,44.9802854],[-76.9023061,43.8024568],[-78.7623935,43.6249578],[-79.15798,43.4462589],[-79.0060087,42.8005317],[-82.662475,41.6889458],[-82.1761642,43.588535],[-83.2813977,46.138853],[-87.5064535,48.0142702],[-88.3492194,48.2963271],[-89.4353148,47.9837822],[-93.9981078,49.0067142],[-95.1105379,49.412004],[-96.0131199,49.0060547],[-123.3228926,49.0042878],[-123.2275233,48.1849927],[-124.7617886,48.4130148]],[[-160.5787616,22.5062947],[-160.5782192,21.4984647],[-158.7470604,21.2439843],[-157.5083185,20.995803],[-155.9961942,18.7790194],[-154.6217803,18.7586966],[-154.6890176,19.8805722],[-156.2927622,21.2225888],[-157.5047384,21.9984962],[-159.0093692,22.5070181],[-160.5787616,22.5062947]],[[-167.1571546,68.721974],[-164.8553982,67.0255078],[-168.002195,66.0017503],[-169.0087448,66.001546],[-169.0075381,64.9987675],[-172.5143281,63.8767267],[-173.8197023,59.74014],[-162.5018149,58.0005815],[-160.0159024,58.0012389],[-160.0149725,57.000035],[-160.5054788,56.9999017],[-165.8092575,54.824847],[-178.000097,52.2446469],[-177.9992996,51.2554252],[-171.4689067,51.8215329],[-162.40251,53.956664],[-159.0075717,55.002502],[-158.0190709,55.0027849],[-151.9963213,55.9991902],[-151.500341,57.9987853],[-151.5012894,58.9919816],[-138.5159989,58.9953194],[-138.5150471,57.9986434],[-133.9948193,54.0031685],[-130.0044418,54.0043387],[-130.0070826,57.0000507],[-131.975877,56.9995156],[-135.1229873,59.756601],[-138.0071813,59.991805],[-139.1715881,60.4127229],[-140.9874011,61.0118551],[-140.9683975,69.9535069],[-156.176891,71.5633329],[-160.413634,70.7397728],[-163.0218273,69.9707435],[-164.9717003,68.994689],[-167.1571546,68.721974]]],"overlay":true},{"id":"geodata.state.nj.us-Infrared2015","name":"NJ 2015 Aerial Imagery (Infrared)","type":"tms","template":"http://whoots.mapwarper.net/tms/{zoom}/{x}/{y}/Infrared2015/http://geodata.state.nj.us/imagerywms/Infrared2015","description":"Digital orthophotography of New Jersey, Near Infrared, 1 foot resolution","scaleExtent":[0,20],"polygon":[[[-74.86599,40.085427],[-74.840927,40.107225],[-74.822903,40.130329],[-74.788055,40.124685],[-74.726086,40.149488],[-74.729176,40.16392],[-74.763336,40.191725],[-74.775524,40.214276],[-74.844017,40.247957],[-74.868393,40.291573],[-74.944611,40.33817],[-74.967098,40.395195],[-75.002632,40.406046],[-75.026836,40.402516],[-75.06134,40.416502],[-75.074215,40.455046],[-75.069065,40.536503],[-75.102367,40.567024],[-75.135927,40.573609],[-75.16777,40.559069],[-75.197639,40.573674],[-75.203733,40.618318],[-75.205064,40.691312],[-75.198326,40.753889],[-75.172405,40.780671],[-75.1367,40.777292],[-75.090179,40.822383],[-75.100994,40.839269],[-75.096874,40.850956],[-75.068464,40.850372],[-75.057049,40.867574],[-75.13773,40.973094],[-75.135155,40.994411],[-75.039024,41.03819],[-74.981518,41.112598],[-74.905472,41.170384],[-74.84024,41.278645],[-74.798012,41.322685],[-74.757156,41.347691],[-74.695702,41.360576],[-74.041054,41.059088],[-74.041051,41.059087],[-74.04105,41.059087],[-74.04105,41.059086],[-74.041049,41.059086],[-74.041049,41.059086],[-73.890266,40.998039],[-73.933406,40.882078],[-73.933407,40.882077],[-73.933408,40.882076],[-73.933408,40.882075],[-73.933408,40.882075],[-74.011459,40.75558],[-74.024543,40.709436],[-74.066048,40.651732],[-74.152222,40.638967],[-74.183121,40.644568],[-74.200459,40.631281],[-74.199257,40.598444],[-74.21505,40.558026],[-74.246807,40.548113],[-74.24715,40.519541],[-74.267578,40.489651],[-74.26054,40.469282],[-74.199257,40.445641],[-74.181061,40.460401],[-74.136429,40.459095],[-73.997555,40.413496],[-74.026566,40.47777],[-74.003906,40.484037],[-73.977814,40.452042],[-73.964767,40.33189],[-74.088364,39.756824],[-74.356842,39.383406],[-74.609528,39.215231],[-74.776382,38.998909],[-74.863586,38.931639],[-74.931221,38.920688],[-74.980316,38.930304],[-74.960747,39.00798],[-74.905472,39.100226],[-74.899979,39.164141],[-75.101166,39.201398],[-75.135498,39.171062],[-75.425949,39.378099],[-75.475044,39.43195],[-75.543365,39.457403],[-75.552292,39.482845],[-75.538902,39.541911],[-75.519676,39.56997],[-75.571175,39.608069],[-75.577698,39.625524],[-75.539932,39.656456],[-75.472984,39.747454],[-75.466253,39.750761],[-75.466252,39.750762],[-75.466252,39.750763],[-75.466252,39.750763],[-75.466252,39.750763],[-75.466251,39.750764],[-75.466251,39.750765],[-75.466251,39.750765],[-75.466251,39.750765],[-75.466251,39.750765],[-75.46625,39.750767],[-75.466249,39.750768],[-75.466249,39.750769],[-75.466249,39.750769],[-75.465088,39.764478],[-75.415041,39.801786],[-75.324669,39.858891],[-75.246048,39.864689],[-75.143738,39.900255],[-75.142365,39.957912],[-75.07061,39.987117],[-75.056534,40.008683],[-74.935341,40.072555],[-74.86599,40.085427]]],"terms_url":"https://njgin.state.nj.us/NJ_NJGINExplorer/ShowMetadata.jsp?docId={E30775F2-6370-4525-8E68-C371ED29BBB3}","terms_text":"NJ Office of Information Technology (NJOIT), Office of Geographic Information Systems (OGIS)"},{"id":"geodata.state.nj.us-Natural2015","name":"NJ 2015 Aerial Imagery (Natural Color)","type":"tms","template":"http://whoots.mapwarper.net/tms/{zoom}/{x}/{y}/Natural2015/http://geodata.state.nj.us/imagerywms/Natural2015","description":"Digital orthophotography of New Jersey, Natural Color, 1 foot resolution","scaleExtent":[0,20],"polygon":[[[-74.86599,40.085427],[-74.840927,40.107225],[-74.822903,40.130329],[-74.788055,40.124685],[-74.726086,40.149488],[-74.729176,40.16392],[-74.763336,40.191725],[-74.775524,40.214276],[-74.844017,40.247957],[-74.868393,40.291573],[-74.944611,40.33817],[-74.967098,40.395195],[-75.002632,40.406046],[-75.026836,40.402516],[-75.06134,40.416502],[-75.074215,40.455046],[-75.069065,40.536503],[-75.102367,40.567024],[-75.135927,40.573609],[-75.16777,40.559069],[-75.197639,40.573674],[-75.203733,40.618318],[-75.205064,40.691312],[-75.198326,40.753889],[-75.172405,40.780671],[-75.1367,40.777292],[-75.090179,40.822383],[-75.100994,40.839269],[-75.096874,40.850956],[-75.068464,40.850372],[-75.057049,40.867574],[-75.13773,40.973094],[-75.135155,40.994411],[-75.039024,41.03819],[-74.981518,41.112598],[-74.905472,41.170384],[-74.84024,41.278645],[-74.798012,41.322685],[-74.757156,41.347691],[-74.695702,41.360576],[-74.041054,41.059088],[-74.041051,41.059087],[-74.04105,41.059087],[-74.04105,41.059086],[-74.041049,41.059086],[-74.041049,41.059086],[-73.890266,40.998039],[-73.933406,40.882078],[-73.933407,40.882077],[-73.933408,40.882076],[-73.933408,40.882075],[-73.933408,40.882075],[-74.011459,40.75558],[-74.024543,40.709436],[-74.066048,40.651732],[-74.152222,40.638967],[-74.183121,40.644568],[-74.200459,40.631281],[-74.199257,40.598444],[-74.21505,40.558026],[-74.246807,40.548113],[-74.24715,40.519541],[-74.267578,40.489651],[-74.26054,40.469282],[-74.199257,40.445641],[-74.181061,40.460401],[-74.136429,40.459095],[-73.997555,40.413496],[-74.026566,40.47777],[-74.003906,40.484037],[-73.977814,40.452042],[-73.964767,40.33189],[-74.088364,39.756824],[-74.356842,39.383406],[-74.609528,39.215231],[-74.776382,38.998909],[-74.863586,38.931639],[-74.931221,38.920688],[-74.980316,38.930304],[-74.960747,39.00798],[-74.905472,39.100226],[-74.899979,39.164141],[-75.101166,39.201398],[-75.135498,39.171062],[-75.425949,39.378099],[-75.475044,39.43195],[-75.543365,39.457403],[-75.552292,39.482845],[-75.538902,39.541911],[-75.519676,39.56997],[-75.571175,39.608069],[-75.577698,39.625524],[-75.539932,39.656456],[-75.472984,39.747454],[-75.466253,39.750761],[-75.466252,39.750762],[-75.466252,39.750763],[-75.466252,39.750763],[-75.466252,39.750763],[-75.466251,39.750764],[-75.466251,39.750765],[-75.466251,39.750765],[-75.466251,39.750765],[-75.466251,39.750765],[-75.46625,39.750767],[-75.466249,39.750768],[-75.466249,39.750769],[-75.466249,39.750769],[-75.465088,39.764478],[-75.415041,39.801786],[-75.324669,39.858891],[-75.246048,39.864689],[-75.143738,39.900255],[-75.142365,39.957912],[-75.07061,39.987117],[-75.056534,40.008683],[-74.935341,40.072555],[-74.86599,40.085427]]],"terms_url":"https://njgin.state.nj.us/NJ_NJGINExplorer/ShowMetadata.jsp?docId={CDC67AB8-ADA1-4B4B-9087-67A82CB9151C}","terms_text":"NJ Office of Information Technology (NJOIT), Office of Geographic Information Systems (OGIS)"},{"id":"NLS-Bartholomew-hfinch-hist","name":"NLS - Bartholomew Half Inch, 1897-1907","type":"tms","template":"http://geo.nls.uk/mapdata2/bartholomew/great_britain/{zoom}/{x}/{-y}.png","scaleExtent":[0,15],"polygon":[[[-9,49.8],[-9,61.1],[1.9,61.1],[1.9,49.8],[-9,49.8]]],"terms_url":"http://geo.nls.uk/maps/","terms_text":"National Library of Scotland Historic Maps"},{"id":"NLS-OS-7th_Series","name":"NLS - OS 1-inch 7th Series 1955-61","type":"tms","template":"http://geo.nls.uk/mapdata2/os/seventh/{zoom}/{x}/{-y}.png","scaleExtent":[5,16],"polygon":[[[-6.4585407,49.9044128],[-6.3872009,49.9841116],[-6.2296827,49.9896159],[-6.2171269,49.8680087],[-6.4551164,49.8591793],[-6.4585407,49.9044128]],[[-1.4495137,60.8634056],[-0.7167114,60.8545122],[-0.7349744,60.4359756],[-0.6938826,60.4168218],[-0.7258429,60.3942735],[-0.7395401,60.0484714],[-0.9267357,60.0461918],[-0.9381501,59.8266157],[-1.4586452,59.831205],[-1.4455187,60.0535999],[-1.463211,60.0535999],[-1.4643524,60.0630002],[-1.5716475,60.0638546],[-1.5693646,60.1790005],[-1.643558,60.1807033],[-1.643558,60.1892162],[-1.8216221,60.1894999],[-1.8204807,60.3615507],[-1.8415973,60.3697345],[-1.8216221,60.3832755],[-1.8179852,60.5934321],[-1.453168,60.5934321],[-1.4495137,60.8634056]],[[-4.9089213,54.4242078],[-4.282598,54.4429861],[-4.2535417,54.029769],[-4.8766366,54.0221831],[-4.9089213,54.4242078]],[[-5.8667408,59.1444603],[-5.7759966,59.1470945],[-5.7720016,59.1014052],[-5.8621751,59.0990605],[-5.8667408,59.1444603]],[[-1.7065887,59.5703599],[-1.5579165,59.5693481],[-1.5564897,59.4965695],[-1.7054472,59.4975834],[-1.7065887,59.5703599]],[[-7.6865827,58.2940975],[-7.5330594,58.3006957],[-7.5256401,58.2646905],[-7.6797341,58.2577853],[-7.6865827,58.2940975]],[[-4.5338281,59.0359871],[-4.481322,59.0371616],[-4.4796099,59.0186583],[-4.5332574,59.0180707],[-4.5338281,59.0359871]],[[-8.6710698,57.8769896],[-8.4673234,57.8897332],[-8.4467775,57.7907],[-8.6510947,57.7779213],[-8.6710698,57.8769896]],[[-5.2395519,50.3530581],[-5.7920073,50.3384899],[-5.760047,49.9317027],[-4.6551363,49.9581461],[-4.677965,50.2860073],[-4.244219,50.2801723],[-4.2487848,50.2042525],[-3.3812929,50.2042525],[-3.4223846,50.5188201],[-3.1164796,50.5246258],[-3.1210453,50.6579592],[-2.6736357,50.6619495],[-2.5953453,50.6394325],[-2.5905026,50.5728419],[-2.4791203,50.5733545],[-2.4758919,50.5066704],[-2.3967943,50.5056438],[-2.401637,50.5723293],[-1.0400296,50.5718167],[-1.0335726,50.7059289],[-0.549302,50.7038843],[-0.5460736,50.7886618],[-0.0924734,50.7856002],[-0.0876307,50.7181949],[0.4789659,50.7120623],[0.487037,50.8182467],[0.9761503,50.8049868],[0.9922927,51.0126311],[1.4491213,51.0004424],[1.4781775,51.4090372],[1.0229632,51.4271576],[1.035877,51.7640881],[1.6105448,51.7500992],[1.646058,52.1560003],[1.7267698,52.1540195],[1.749369,52.4481811],[1.7870672,52.4811624],[1.759102,52.522505],[1.7933451,52.9602749],[0.3798147,52.9958468],[0.3895238,53.2511239],[0.3478614,53.2511239],[0.3238912,53.282186],[0.3461492,53.6538501],[0.128487,53.6575466],[0.116582,53.6674703],[0.1350586,54.0655731],[-0.0609831,54.065908],[-0.0414249,54.4709448],[-0.5662701,54.4771794],[-0.5592078,54.6565127],[-1.1665638,54.6623485],[-1.1637389,54.842611],[-1.3316194,54.843909],[-1.3257065,55.2470842],[-1.529453,55.2487108],[-1.524178,55.6540122],[-1.7638798,55.6540122],[-1.7733693,55.9719116],[-2.1607858,55.9682981],[-2.1543289,56.0621387],[-2.4578051,56.0585337],[-2.4190635,56.641717],[-2.0962164,56.641717],[-2.0833025,57.0021322],[-1.9283359,57.0126802],[-1.9180966,57.3590895],[-1.7502161,57.3625721],[-1.7695869,57.7608634],[-3.6937554,57.7574187],[-3.7066693,57.9806386],[-3.5969013,57.9772149],[-3.6033582,58.1207277],[-3.0222335,58.1309566],[-3.0286905,58.5410788],[-2.8478961,58.530968],[-2.86081,58.8430508],[-2.679624,58.8414991],[-2.6841897,58.885175],[-2.6339665,58.9052239],[-2.679624,58.9335083],[-2.6887555,59.0229231],[-2.3668703,59.0229231],[-2.3702946,59.2652861],[-2.3429001,59.2821989],[-2.3714361,59.2996861],[-2.3737189,59.3707083],[-2.3429001,59.385825],[-2.3725775,59.400354],[-2.3714361,59.4259098],[-3.0734196,59.4230067],[-3.0711368,59.3433649],[-3.103097,59.3311405],[-3.0745611,59.3136695],[-3.0722782,59.232603],[-3.3850319,59.1484167],[-3.3747589,58.9352753],[-3.5653789,58.9323303],[-3.554829,58.69759],[-5.2808579,58.6667732],[-5.2534159,58.3514125],[-5.5068508,58.3437887],[-5.4761804,58.0323557],[-5.8974958,58.0212436],[-5.8522972,57.6171758],[-6.1396311,57.6137174],[-6.1541592,57.7423183],[-6.2913692,57.7380102],[-6.3365678,58.1398784],[-6.1121891,58.1466944],[-6.1473778,58.5106285],[-6.2934817,58.5416182],[-6.8413713,58.2977321],[-7.0057382,58.2929331],[-7.1016189,58.2064403],[-7.2573132,58.1793148],[-7.2531092,58.1004928],[-7.4070698,58.0905566],[-7.391347,57.7911354],[-7.790991,57.7733151],[-7.7624215,57.5444165],[-7.698501,57.1453194],[-7.7943817,57.1304547],[-7.716764,56.7368628],[-7.0122067,56.7654359],[-6.979922,56.5453858],[-7.0638622,56.5453858],[-7.0444914,56.3562587],[-6.500676,56.3812917],[-6.4491433,55.9793649],[-6.563287,55.9691456],[-6.5393742,55.7030135],[-6.5595521,55.6907321],[-6.5345315,55.6761713],[-6.5216176,55.5704434],[-5.8912587,55.5923416],[-5.8560127,55.2320733],[-5.2293639,55.2515958],[-5.1837064,54.6254139],[-3.6655956,54.6518373],[-3.6496155,54.4320023],[-3.5400375,54.4306744],[-3.530906,54.0290181],[-3.0697656,54.030359],[-3.0675737,53.8221388],[-3.0804876,53.7739911],[-3.0619239,53.7477488],[-3.0611168,53.6737049],[-3.2144691,53.6708361],[-3.2057699,53.4226163],[-3.2799632,53.355224],[-3.2896655,53.3608441],[-3.3327547,53.364931],[-3.3761293,53.3540318],[-4.0888976,53.3433102],[-4.0945474,53.4612036],[-4.697412,53.4448624],[-4.6882805,53.3318598],[-4.7202407,53.2895771],[-4.6837148,53.2486184],[-4.6768661,53.1542644],[-4.8480816,53.1446807],[-4.8178336,52.7440299],[-4.2545751,52.7558939],[-4.228876,52.254876],[-4.2607571,52.2536408],[-4.2724603,52.2432637],[-4.8136263,52.230095],[-4.8079191,52.1138892],[-5.3889104,52.0991668],[-5.3717888,51.9129667],[-5.4208706,51.9101502],[-5.414022,51.8453218],[-5.3683645,51.8474373],[-5.3466772,51.5595332],[-4.773676,51.5758518],[-4.7656859,51.4885146],[-4.1915432,51.4970427],[-4.1869775,51.4344663],[-3.6151177,51.4444274],[-3.6105519,51.3746543],[-3.1494115,51.3789292],[-3.1494115,51.2919281],[-4.3038735,51.2745907],[-4.2861169,51.0508721],[-4.8543277,51.0366633],[-4.8372201,50.7212787],[-5.2618345,50.7082694],[-5.2395519,50.3530581]],[[-2.1502671,60.171318],[-2.0030218,60.1696146],[-2.0013096,60.0997023],[-2.148555,60.1011247],[-2.1502671,60.171318]],[[-6.2086011,59.1163488],[-6.1229934,59.1166418],[-6.121852,59.0714985],[-6.2097426,59.0714985],[-6.2086011,59.1163488]],[[-4.4159559,59.0889036],[-4.4212022,59.0770848],[-4.3971904,59.0779143],[-4.3913388,59.0897328],[-4.4159559,59.0889036]]],"terms_url":"http://geo.nls.uk/maps/","terms_text":"National Library of Scotland Historic Maps"},{"id":"NLS-OS-1st_Series","name":"NLS - OS 1:25k 1st Series 1937-61","type":"tms","template":"http://geo.nls.uk/mapdata2/os/25000/{zoom}/{x}/{-y}.png","scaleExtent":[5,16],"polygon":[[[-4.7157244,54.6796556],[-4.6850662,54.6800268],[-4.6835779,54.6623245],[-4.7148782,54.6615818],[-4.7157244,54.6796556]],[[-3.7085748,58.3371151],[-3.5405937,58.3380684],[-3.5315137,58.1608002],[-3.3608086,58.1622372],[-3.3653486,58.252173],[-3.1610473,58.2536063],[-3.1610473,58.3261509],[-3.0275704,58.3271045],[-3.0366505,58.6139001],[-3.0021463,58.614373],[-3.0030543,58.7036341],[-3.4180129,58.7003322],[-3.4171049,58.6290293],[-3.7240109,58.6266658],[-3.7231029,58.606806],[-4.2361262,58.5992374],[-4.2334022,58.5092347],[-3.88836,58.5144516],[-3.8829119,58.4261327],[-3.7158389,58.4270836],[-3.7085748,58.3371151]],[[-6.46676,49.9943621],[-6.1889102,50.004868],[-6.1789222,49.8967815],[-6.3169391,49.8915171],[-6.312399,49.8200979],[-6.4504159,49.8159968],[-6.46676,49.9943621]],[[-5.6453263,50.2029809],[-5.7801329,50.2014076],[-5.7637888,50.0197267],[-5.3479221,50.0290604],[-5.3388421,49.9414854],[-5.024672,49.9473287],[-5.0355681,50.0383923],[-5.0010639,50.0453901],[-4.9974319,50.1304478],[-4.855783,50.13394],[-4.861231,50.206057],[-4.6546085,50.2140172],[-4.6558926,50.3018616],[-4.5184924,50.3026818],[-4.51464,50.325642],[-4.2488284,50.3264618],[-4.2488284,50.3100631],[-4.10886,50.3141633],[-4.1062917,50.2411267],[-3.9648088,50.2432047],[-3.9640778,50.2254158],[-3.8522287,50.2273626],[-3.8503757,50.1552563],[-3.6921809,50.1572487],[-3.5414602,50.1602198],[-3.5465781,50.3226814],[-3.4068012,50.3241013],[-3.4165761,50.5892711],[-3.2746691,50.5962721],[-3.2749172,50.6106323],[-2.9971742,50.613972],[-2.9896008,50.688537],[-2.7120266,50.690565],[-2.710908,50.6195964],[-2.5695473,50.6157538],[-2.5651019,50.5134083],[-2.4014463,50.513379],[-2.3940583,50.6160348],[-2.2894123,50.6147436],[-2.2876184,50.6008549],[-2.1477855,50.6048506],[-2.1451013,50.5325437],[-1.9335117,50.5347477],[-1.9362139,50.6170445],[-1.8573025,50.6228094],[-1.8554865,50.709139],[-1.6066929,50.709139],[-1.6085089,50.6239615],[-1.4450678,50.6228094],[-1.4432518,50.5317039],[-1.1545059,50.5293951],[-1.1472419,50.6170485],[-1.011041,50.6205051],[-1.011041,50.7056889],[-0.704135,50.7045388],[-0.700503,50.7769401],[-0.5860943,50.7723465],[-0.5879103,50.7907181],[-0.0149586,50.7798108],[-0.0185906,50.7625836],[0.0967261,50.7620093],[0.0921861,50.6913106],[0.3046595,50.6890096],[0.3101075,50.7757917],[0.5511831,50.7726336],[0.5529991,50.8432096],[0.695556,50.8403428],[0.696464,50.8592608],[0.9852099,50.8523824],[0.9906579,50.9417226],[1.0160821,50.9411504],[1.0215301,51.0303204],[1.2812198,51.0240383],[1.2848518,51.0948044],[1.4277848,51.0948044],[1.4386809,51.2882859],[1.4713691,51.2871502],[1.4804492,51.3994534],[1.1590151,51.4073836],[1.1590151,51.3869889],[1.0191822,51.3903886],[1.0228142,51.4798247],[0.8793493,51.4843484],[0.8829813,51.5566675],[1.0264462,51.5544092],[1.0373423,51.7493319],[1.2607117,51.7482076],[1.2661598,51.8279642],[1.3351682,51.8335756],[1.3478803,51.9199021],[1.4840812,51.9199021],[1.4986093,52.0038271],[1.6438902,52.0027092],[1.6656823,52.270221],[1.7310588,52.270221],[1.7528509,52.4465637],[1.8254914,52.4476705],[1.8345714,52.624408],[1.7690346,52.6291402],[1.7741711,52.717904],[1.6996925,52.721793],[1.706113,52.8103687],[1.559724,52.8165777],[1.5648605,52.9034116],[1.4184715,52.9103818],[1.4223238,52.9281894],[1.3439928,52.9289635],[1.3491293,53.0001194],[0.4515789,53.022589],[0.4497629,52.9351139],[0.3789384,52.9351139],[0.3716744,52.846365],[0.2227614,52.8496552],[0.2336575,52.9329248],[0.3062979,52.9351139],[0.308114,53.022589],[0.3807544,53.0236813],[0.3993708,53.2933729],[0.3248922,53.2987454],[0.3274604,53.3853782],[0.2504136,53.38691],[0.2581183,53.4748924],[0.1862079,53.4779494],[0.1913443,53.6548777],[0.1502527,53.6594436],[0.1528209,53.7666003],[0.0012954,53.7734308],[0.0025796,53.8424326],[-0.0282392,53.841675],[-0.0226575,53.9311501],[-0.1406983,53.9322193],[-0.1416063,54.0219323],[-0.1706625,54.0235326],[-0.1679384,54.0949482],[-0.0126694,54.0912206],[-0.0099454,54.1811226],[-0.1615824,54.1837795],[-0.1606744,54.2029038],[-0.2405789,54.2034349],[-0.2378549,54.2936234],[-0.3894919,54.2941533],[-0.3857497,54.3837321],[-0.461638,54.3856364],[-0.4571122,54.4939066],[-0.6105651,54.4965434],[-0.6096571,54.5676704],[-0.7667421,54.569776],[-0.7640181,54.5887213],[-0.9192871,54.5908258],[-0.9148116,54.6608348],[-1.1485204,54.6634343],[-1.1472363,54.7528316],[-1.2268514,54.7532021],[-1.2265398,54.8429879],[-1.2991803,54.8435107],[-1.2991803,54.9333391],[-1.3454886,54.9354258],[-1.3436726,55.0234878],[-1.3772688,55.0255698],[-1.3754528,55.1310877],[-1.4997441,55.1315727],[-1.4969272,55.2928323],[-1.5296721,55.2942946],[-1.5258198,55.6523803],[-1.7659492,55.6545537],[-1.7620968,55.7435626],[-1.9688392,55.7435626],[-1.9698023,55.8334505],[-2.0019051,55.8336308],[-2.0015841,55.9235526],[-2.1604851,55.9240613],[-2.1613931,55.9413549],[-2.3202942,55.9408463],[-2.3212022,56.0145126],[-2.5627317,56.0124824],[-2.5645477,56.1022207],[-2.9658863,56.0991822],[-2.9667943,56.1710304],[-2.4828272,56.1755797],[-2.4882752,56.2856078],[-2.5645477,56.2835918],[-2.5681798,56.3742075],[-2.7261728,56.3732019],[-2.7316208,56.4425301],[-2.6190281,56.4425301],[-2.6153961,56.5317671],[-2.453771,56.5347715],[-2.4534686,56.6420248],[-2.4062523,56.6440218],[-2.3953562,56.7297964],[-2.2936596,56.7337811],[-2.2972916,56.807423],[-2.1629067,56.8113995],[-2.1592747,56.9958425],[-1.9922016,57.0017771],[-2.0067297,57.2737477],[-1.9195612,57.2757112],[-1.9304572,57.3482876],[-1.8106005,57.3443682],[-1.7997044,57.4402728],[-1.6616875,57.4285429],[-1.6689516,57.5398256],[-1.7452241,57.5398256],[-1.7524881,57.6313302],[-1.8287606,57.6332746],[-1.8287606,57.7187255],[-3.1768526,57.7171219],[-3.1794208,57.734264],[-3.5134082,57.7292105],[-3.5129542,57.7112683],[-3.7635638,57.7076303],[-3.7598539,57.635713],[-3.8420372,57.6343382],[-3.8458895,57.6178365],[-3.9794374,57.6157733],[-3.9794374,57.686544],[-3.8150708,57.689976],[-3.817639,57.7968899],[-3.6853753,57.7989429],[-3.6892276,57.8891567],[-3.9383458,57.8877915],[-3.9421981,57.9750592],[-3.6943641,57.9784638],[-3.6969323,58.0695865],[-4.0372226,58.0641528],[-4.0346543,57.9730163],[-4.2003051,57.9702923],[-4.1832772,57.7012869],[-4.518752,57.6951111],[-4.5122925,57.6050682],[-4.6789116,57.6016628],[-4.666022,57.4218334],[-3.6677696,57.4394729],[-3.671282,57.5295384],[-3.3384979,57.5331943],[-3.3330498,57.4438859],[-2.8336466,57.4485275],[-2.8236396,56.9992706],[-2.3305398,57.0006693],[-2.3298977,56.9113932],[-2.6579889,56.9092901],[-2.6559637,56.8198406],[-2.8216747,56.8188467],[-2.8184967,56.7295397],[-3.1449248,56.7265508],[-3.1435628,56.6362749],[-3.4679089,56.6350265],[-3.474265,56.7238108],[-3.8011471,56.7188284],[-3.785711,56.4493026],[-3.946428,56.4457896],[-3.9428873,56.2659777],[-4.423146,56.2588459],[-4.4141572,56.0815506],[-4.8944159,56.0708008],[-4.8791072,55.8896994],[-5.1994158,55.8821374],[-5.1852906,55.7023791],[-5.0273445,55.7067203],[-5.0222081,55.6879046],[-4.897649,55.6907999],[-4.8880181,55.6002822],[-4.7339244,55.6046348],[-4.7275038,55.5342082],[-4.773732,55.5334815],[-4.7685955,55.4447227],[-4.8494947,55.4418092],[-4.8405059,55.3506535],[-4.8700405,55.3513836],[-4.8649041,55.2629462],[-4.9920314,55.2592875],[-4.9907473,55.1691779],[-5.0600894,55.1655105],[-5.0575212,55.0751884],[-5.2141831,55.0722477],[-5.1991766,54.8020337],[-5.0466316,54.8062205],[-5.0502636,54.7244996],[-4.9703591,54.7203043],[-4.9776232,54.6215905],[-4.796022,54.6342056],[-4.796022,54.7307917],[-4.8977186,54.7265971],[-4.9086147,54.8145928],[-4.8069181,54.8166856],[-4.8105501,54.7915648],[-4.6943253,54.7978465],[-4.6761652,54.7244996],[-4.5744686,54.7244996],[-4.5599405,54.6426135],[-4.3093309,54.6384098],[-4.3333262,54.8229889],[-4.2626999,54.8274274],[-4.2549952,54.7348587],[-3.8338058,54.7400481],[-3.836374,54.8141105],[-3.7118149,54.8133706],[-3.7143831,54.8318654],[-3.5346072,54.8355633],[-3.5271039,54.9066228],[-3.4808758,54.9084684],[-3.4776655,54.7457328],[-3.5874573,54.744621],[-3.5836049,54.6546166],[-3.7107322,54.6531308],[-3.6991752,54.4550407],[-3.5746161,54.4572801],[-3.5759002,54.3863042],[-3.539945,54.3855564],[-3.5386609,54.297224],[-3.46033,54.2957252],[-3.4590458,54.2079507],[-3.3807149,54.2102037],[-3.381999,54.1169788],[-3.302878,54.1160656],[-3.300154,54.0276224],[-3.1013007,54.0292224],[-3.093596,53.6062158],[-3.2065981,53.6016441],[-3.2091663,53.4917753],[-3.2451215,53.4887193],[-3.2348486,53.4045934],[-3.5276266,53.3999999],[-3.5343966,53.328481],[-3.6488053,53.3252272],[-3.6527308,53.3057716],[-3.7271873,53.3046865],[-3.7315003,53.3945257],[-3.9108315,53.3912769],[-3.9071995,53.3023804],[-3.9521457,53.3015665],[-3.9566724,53.3912183],[-4.1081979,53.3889209],[-4.1081979,53.4072967],[-4.2622916,53.4065312],[-4.2635757,53.4753707],[-4.638537,53.4677274],[-4.6346847,53.3812621],[-4.7091633,53.3774321],[-4.7001745,53.1954965],[-4.5499332,53.1962658],[-4.5435126,53.1092488],[-4.3919871,53.1100196],[-4.3855666,53.0236002],[-4.6115707,53.0205105],[-4.603866,52.9284932],[-4.7566756,52.9261709],[-4.7476868,52.8370555],[-4.8208813,52.8331768],[-4.8208813,52.7446476],[-4.3701572,52.7539749],[-4.3765778,52.8401583],[-4.2314728,52.8455875],[-4.2237682,52.7586379],[-4.1056297,52.7570836],[-4.1015192,52.6714874],[-4.1487355,52.6703862],[-4.1305754,52.4008596],[-4.1995838,52.3986435],[-4.2050319,52.3110195],[-4.3466808,52.303247],[-4.3484968,52.2365693],[-4.4901457,52.2332328],[-4.4883297,52.2098702],[-4.6572188,52.2098702],[-4.6590348,52.1385939],[-4.7788916,52.13525],[-4.7807076,52.1162967],[-4.9259885,52.1140663],[-4.9187245,52.0392855],[-5.2365265,52.0314653],[-5.2347105,51.9442339],[-5.3473032,51.9408755],[-5.3473032,51.9195995],[-5.4925842,51.9162392],[-5.4853201,51.8265386],[-5.1983903,51.8321501],[-5.1893102,51.7625177],[-5.335825,51.7589528],[-5.3281204,51.6686495],[-5.1836575,51.6730296],[-5.1836575,51.6539134],[-5.0674452,51.6578966],[-5.0603825,51.5677905],[-4.5974594,51.5809588],[-4.60388,51.6726314],[-4.345773,51.6726314],[-4.3355001,51.4962964],[-3.9528341,51.5106841],[-3.9425611,51.5905333],[-3.8809237,51.5953198],[-3.8706508,51.5074872],[-3.7679216,51.4978952],[-3.7550805,51.4242895],[-3.5855774,51.41468],[-3.5778727,51.3329177],[-3.0796364,51.3329177],[-3.0770682,51.2494018],[-3.7216935,51.2381477],[-3.7216935,51.2558315],[-3.8706508,51.2558315],[-3.8680825,51.2365398],[-4.2944084,51.2252825],[-4.289272,51.0496352],[-4.5692089,51.0431767],[-4.5624122,50.9497388],[-4.5905604,50.9520269],[-4.5896524,50.8627065],[-4.6296046,50.8592677],[-4.6226411,50.7691513],[-4.6952816,50.7680028],[-4.6934655,50.6967379],[-4.8342064,50.6938621],[-4.8296664,50.6046231],[-4.9676833,50.6000126],[-4.9685913,50.5821427],[-5.1084242,50.5786832],[-5.1029762,50.4892254],[-5.1311244,50.48807],[-5.1274923,50.4163798],[-5.2664172,50.4117509],[-5.2609692,50.3034214],[-5.5124868,50.2976214],[-5.5061308,50.2256428],[-5.6468717,50.2209953],[-5.6453263,50.2029809]],[[-5.1336607,55.2630226],[-5.1021999,55.2639372],[-5.0999527,55.2458239],[-5.1322161,55.2446343],[-5.1336607,55.2630226]],[[-5.6431878,55.5095745],[-5.4861028,55.5126594],[-5.4715747,55.3348829],[-5.6277517,55.3302345],[-5.6431878,55.5095745]],[[-4.7213517,51.2180246],[-4.5804201,51.2212417],[-4.5746416,51.1306736],[-4.7174993,51.1280545],[-4.7213517,51.2180246]],[[-5.1608796,55.4153626],[-5.0045387,55.4190069],[-5.0184798,55.6153521],[-5.1755648,55.6138137],[-5.1608796,55.4153626]]],"terms_url":"http://geo.nls.uk/maps/","terms_text":"National Library of Scotland Historic Maps"},{"id":"NLS-OS-25inch-hist","name":"NLS - OS 25-inch (Scotland), 1892-1905","type":"tms","template":"http://geo.nls.uk/mapdata2/os/25_inch/scotland_1/{zoom}/{x}/{y}.png","scaleExtent":[0,18],"polygon":[[[-9.25,54.43],[-9.25,61.12],[0.22,61.12],[0.22,54.43],[-9.25,54.43]]],"terms_url":"http://geo.nls.uk/maps/","terms_text":"National Library of Scotland Historic Maps"},{"id":"NLS-OS-6inch-County-Series-hist","name":"NLS - OS 6-inch County Series, 1888-1913","type":"tms","template":"http://geo.nls.uk/mapdata3/os/6_inch_gb_1900/{zoom}/{x}/{y}.png","scaleExtent":[0,17],"polygon":[[[-9,49.8],[-9,61.1],[1.9,61.1],[1.9,49.8],[-9,49.8]]],"terms_url":"http://geo.nls.uk/maps/","terms_text":"National Library of Scotland Historic Maps"},{"id":"NLS-OS-6inch-Scotland-hist","name":"NLS - OS 6-inch Scotland 1842-82","type":"tms","template":"http://geo.nls.uk/maps/os/six_inch/{zoom}/{x}/{-y}.png","scaleExtent":[5,16],"polygon":[[[-5.2112173,54.8018593],[-5.0642752,54.8026508],[-5.0560354,54.6305176],[-4.3158316,54.6297227],[-4.3117117,54.7448258],[-3.8530325,54.7464112],[-3.8530325,54.8034424],[-3.5522818,54.8034424],[-3.5522818,54.8374644],[-3.468511,54.8406277],[-3.4657644,54.8983158],[-3.3847403,54.8991055],[-3.3888601,54.9559214],[-3.0920786,54.9539468],[-3.0392359,54.9923274],[-3.0212713,55.0493881],[-2.9591232,55.0463283],[-2.9202807,55.0666294],[-2.7857081,55.068652],[-2.7852225,55.0914426],[-2.7337562,55.0922761],[-2.737616,55.151204],[-2.7648395,55.1510672],[-2.7013114,55.1722505],[-2.6635459,55.2192808],[-2.6460364,55.2188891],[-2.629042,55.2233933],[-2.6317886,55.2287781],[-2.6235488,55.2446345],[-2.6197723,55.2454663],[-2.6099017,55.2454174],[-2.6099876,55.2486466],[-2.6408121,55.2590039],[-2.6247896,55.2615631],[-2.6045186,55.2823081],[-2.5693176,55.296132],[-2.5479542,55.3121617],[-2.5091116,55.3234891],[-2.4780376,55.3494471],[-2.4421083,55.3533118],[-2.4052079,55.3439256],[-2.3726772,55.3447539],[-2.3221819,55.3687665],[-2.3241241,55.3999337],[-2.2576062,55.425015],[-2.1985547,55.4273529],[-2.1484296,55.4717466],[-2.1944348,55.484199],[-2.2040479,55.529306],[-2.2960584,55.6379722],[-2.2177808,55.6379722],[-2.1059266,55.7452498],[-1.9716874,55.7462161],[-1.9697453,55.9190951],[-2.1201694,55.9207115],[-2.1242893,55.9776133],[-2.3440159,55.9783817],[-2.3440159,56.0390349],[-2.5046909,56.0413363],[-2.500571,56.1003588],[-2.8823459,56.0957629],[-2.8823459,56.1722898],[-2.4126804,56.1692316],[-2.4181736,56.2334017],[-2.5857151,56.2303484],[-2.5719822,56.3416356],[-2.7257908,56.3462022],[-2.7312839,56.4343808],[-2.6928318,56.4343808],[-2.6928318,56.4859769],[-2.5307834,56.4935587],[-2.5307834,56.570806],[-2.5302878,56.6047947],[-2.3732428,56.6044452],[-2.3684363,56.7398824],[-2.3292975,56.7398824],[-2.3292975,56.7888065],[-2.3145346,56.7891826],[-2.3148779,56.7967036],[-2.171369,56.7967036],[-2.1703979,56.9710595],[-2.0101725,56.9694716],[-2.0101725,57.0846832],[-2.0817687,57.085349],[-2.0488097,57.1259963],[-2.0409133,57.126369],[-2.0383434,57.2411129],[-1.878118,57.2421638],[-1.8771469,57.2978175],[-1.9868771,57.2983422],[-1.9082209,57.3560063],[-1.8752048,57.3560063],[-1.8761758,57.3769527],[-1.8120857,57.4120111],[-1.7120661,57.4120111],[-1.7034646,57.6441388],[-1.8666032,57.6451781],[-1.8646611,57.7033351],[-3.1204292,57.7064705],[-3.1218025,57.7504652],[-3.4445259,57.7526635],[-3.4472724,57.7138067],[-3.5145637,57.7094052],[-3.5118171,57.6939956],[-3.7645027,57.6917938],[-3.7672492,57.6344975],[-3.842378,57.6288312],[-3.8438346,57.5965825],[-3.9414265,57.5916386],[-3.9404554,57.6537782],[-3.8894746,57.6529989],[-3.8826772,57.7676408],[-3.7224517,57.766087],[-3.7195385,57.8819201],[-3.9146888,57.8853352],[-3.916062,57.9546243],[-3.745774,57.9538956],[-3.7471473,58.0688409],[-3.5837256,58.0695672],[-3.5837256,58.1116689],[-3.4560096,58.1138452],[-3.4544646,58.228503],[-3.4379851,58.2283222],[-3.4243233,58.2427725],[-3.412307,58.2438567],[-3.3735115,58.2695057],[-3.3063919,58.2862038],[-3.1229154,58.2859395],[-3.123602,58.3443661],[-2.9574338,58.3447264],[-2.951254,58.6422011],[-2.8812162,58.6429157],[-2.8851004,58.8112825],[-2.7180775,58.8142997],[-2.7161354,58.8715749],[-2.556881,58.8775984],[-2.5544533,58.9923453],[-2.5567617,59.0483775],[-2.391893,59.0485996],[-2.3918002,59.1106996],[-2.4733695,59.1106996],[-2.5591563,59.1783028],[-2.5630406,59.2210646],[-2.3921334,59.224046],[-2.3911409,59.2740075],[-2.3639512,59.2745036],[-2.3658933,59.285417],[-2.3911409,59.284921],[-2.3911409,59.3379505],[-2.2221759,59.3381981],[-2.2233897,59.395965],[-2.3758467,59.396583],[-2.3899271,59.4026383],[-2.4008516,59.3962122],[-2.5637882,59.3952604],[-2.5637882,59.3385811],[-2.7320164,59.3375306],[-2.7333896,59.3952604],[-3.0726511,59.3931174],[-3.0703404,59.3354759],[-3.0753186,59.3355634],[-3.0749753,59.3292593],[-3.0698254,59.3289091],[-3.069801,59.2196159],[-3.2363384,59.2166341],[-3.2336751,59.1606496],[-3.4032766,59.1588895],[-3.394086,58.9279316],[-3.5664497,58.9259268],[-3.5611089,58.8679885],[-3.392508,58.8699339],[-3.3894734,58.8698711],[-3.3891093,58.8684905],[-3.3912942,58.868616],[-3.3884161,58.7543084],[-3.2238208,58.7555677],[-3.2189655,58.691289],[-3.4634113,58.6905753],[-3.4551716,58.6341518],[-3.787508,58.6341518],[-3.7861347,58.5769211],[-3.9028645,58.5733411],[-3.9028645,58.6477304],[-4.0690327,58.6491594],[-4.0690327,58.5912376],[-4.7364521,58.5933845],[-4.7364521,58.6505884],[-5.0715351,58.6520173],[-5.0654779,58.5325854],[-5.2332047,58.5316087],[-5.2283494,58.4719947],[-5.2424298,58.4719947],[-5.2366034,58.4089731],[-5.2283494,58.4094818],[-5.2210664,58.3005859],[-5.5657939,58.2959933],[-5.5580254,58.2372573],[-5.4146722,58.2401326],[-5.4141866,58.2267768],[-5.3885749,58.2272242],[-5.382714,58.1198615],[-5.51043,58.1191362],[-5.5114011,58.006214],[-5.6745397,58.0041559],[-5.6716266,57.9449366],[-5.6716266,57.8887166],[-5.8347652,57.8856193],[-5.8277052,57.5988958],[-6.0384259,57.5986357],[-6.0389115,57.6459559],[-6.1981658,57.6456961],[-6.2076123,57.7600132],[-6.537067,57.7544033],[-6.5312406,57.6402392],[-6.7002056,57.6360809],[-6.6807844,57.5236293],[-6.8516915,57.5152857],[-6.8361545,57.3385811],[-6.6730158,57.3438213],[-6.674958,57.2850883],[-6.5098772,57.2850883],[-6.4982244,57.1757637],[-6.3506228,57.1820797],[-6.3312015,57.1251969],[-6.1797156,57.1230884],[-6.1719471,57.0682265],[-6.4593819,57.059779],[-6.4564687,57.1093806],[-6.6671895,57.1062165],[-6.6730158,57.002708],[-6.5021087,57.0048233],[-6.4836097,56.8917522],[-6.3266104,56.8894062],[-6.3156645,56.7799312],[-6.2146739,56.775675],[-6.2146739,56.7234965],[-6.6866107,56.7224309],[-6.6769001,56.6114413],[-6.8419809,56.607166],[-6.8400387,56.5483307],[-7.1546633,56.5461895],[-7.1488369,56.4872592],[-6.9915246,56.490476],[-6.9876404,56.4325329],[-6.6827265,56.4314591],[-6.6769001,56.5472601],[-6.5292985,56.5504717],[-6.5234721,56.4379018],[-6.3661598,56.4368281],[-6.3642177,56.3766524],[-6.5273563,56.3712749],[-6.5171745,56.2428427],[-6.4869621,56.247421],[-6.4869621,56.1893882],[-6.3001945,56.1985572],[-6.3029411,56.2581017],[-5.9019401,56.256576],[-5.8964469,56.0960466],[-6.0282829,56.0883855],[-6.0392692,56.1557502],[-6.3853385,56.1542205],[-6.3606193,55.96099],[-6.2123039,55.9640647],[-6.2047508,55.9202269],[-6.5185478,55.9129158],[-6.5061881,55.7501763],[-6.6764762,55.7409005],[-6.6599967,55.6263176],[-6.3551261,55.6232161],[-6.3578727,55.5689002],[-6.0392692,55.5720059],[-6.0310294,55.6247669],[-5.7398917,55.6309694],[-5.7371452,55.4569279],[-5.8964469,55.4600426],[-5.8964469,55.2789864],[-5.4350211,55.2821151],[-5.4405143,55.4506979],[-5.2867057,55.4569279],[-5.3086784,55.4070602],[-4.9735954,55.4008223],[-4.9845817,55.2038242],[-5.1493766,55.2038242],[-5.1411369,55.037337],[-5.2152946,55.0341891],[-5.2112173,54.8018593]],[[-2.1646559,60.1622059],[-1.9930299,60.1609801],[-1.9946862,60.1035151],[-2.1663122,60.104743],[-2.1646559,60.1622059]],[[-1.5360658,59.8570831],[-1.3653566,59.8559841],[-1.366847,59.7975565],[-1.190628,59.7964199],[-1.1862046,59.9695391],[-1.0078652,59.9683948],[-1.0041233,60.114145],[-0.8360832,60.1130715],[-0.834574,60.1716772],[-1.0074262,60.1727795],[-1.0052165,60.2583924],[-0.8299659,60.2572778],[-0.826979,60.3726551],[-0.6507514,60.3715381],[-0.6477198,60.4882292],[-0.9984896,60.4904445],[-0.9970279,60.546555],[-0.6425288,60.5443201],[-0.6394896,60.6606792],[-0.8148133,60.6617806],[-0.8132987,60.7196112],[-0.6383298,60.7185141],[-0.635467,60.8275393],[-0.797568,60.8285523],[-0.9941426,60.8297807],[-0.9954966,60.7782667],[-1.1670282,60.7793403],[-1.1700357,60.6646181],[-1.5222599,60.6668304],[-1.5237866,60.6084426],[-1.6975673,60.609536],[-1.7021271,60.4345249],[-1.5260578,60.4334111],[-1.5275203,60.3770719],[-1.8751127,60.3792746],[-1.8781372,60.2624647],[-1.7019645,60.2613443],[-1.7049134,60.1470532],[-1.528659,60.1459283],[-1.5360658,59.8570831]],[[-0.9847667,60.8943762],[-0.9860347,60.8361105],[-0.8078362,60.8351904],[-0.8065683,60.8934578],[-0.9847667,60.8943762]],[[-7.7696901,56.8788231],[-7.7614504,56.7608274],[-7.6009049,56.7641903],[-7.5972473,56.819332],[-7.4479894,56.8203948],[-7.4489319,56.8794098],[-7.2841369,56.8794098],[-7.2813904,57.0471152],[-7.1303283,57.0515969],[-7.1330749,57.511801],[-6.96828,57.5147514],[-6.9765198,57.6854668],[-6.8062317,57.6913392],[-6.8089782,57.8041985],[-6.6496765,57.8071252],[-6.6441833,57.8612267],[-6.3200866,57.8626878],[-6.3200866,58.1551617],[-6.1607849,58.1522633],[-6.1552917,58.20874],[-5.9850036,58.2101869],[-5.9904968,58.2680163],[-6.1497986,58.2665717],[-6.1415588,58.5557514],[-6.3173401,58.5557514],[-6.3091003,58.4983923],[-6.4876282,58.4955218],[-6.4876282,58.4423768],[-6.6606628,58.4395018],[-6.6469299,58.3819525],[-6.8117248,58.3805125],[-6.8117248,58.3286357],[-6.9792663,58.3286357],[-6.9710266,58.2694608],[-7.1413147,58.2680163],[-7.1403816,58.0358742],[-7.3020636,58.0351031],[-7.3030347,57.9774797],[-7.1379539,57.9777372],[-7.1413526,57.9202792],[-7.1398961,57.8640206],[-7.3020636,57.862471],[-7.298484,57.7442293],[-7.4509193,57.7456951],[-7.4550392,57.6899522],[-7.6186131,57.6906048],[-7.6198341,57.7456951],[-7.7901222,57.7442293],[-7.7873756,57.6855477],[-7.6222332,57.6853817],[-7.6173779,57.5712602],[-7.788285,57.5709998],[-7.7892561,57.512109],[-7.7038025,57.5115874],[-7.6999183,57.4546902],[-7.5367796,57.4552126],[-7.5348375,57.5126306],[-7.4581235,57.5131521],[-7.4552103,57.2824165],[-7.6115515,57.2845158],[-7.6144647,57.2272651],[-7.451326,57.2256881],[-7.451326,57.1103873],[-7.6164068,57.1088053],[-7.603783,56.8792358],[-7.7696901,56.8788231]],[[-1.7106618,59.5626284],[-1.5417509,59.562215],[-1.5423082,59.5037224],[-1.7112191,59.5041365],[-1.7106618,59.5626284]]],"terms_url":"http://geo.nls.uk/maps/","terms_text":"National Library of Scotland Historic Maps"},{"id":"MAPNIK","name":"OpenStreetMap (Standard)","type":"tms","template":"http://{switch:a,b,c}.tile.openstreetmap.org/{zoom}/{x}/{y}.png","description":"The default OpenStreetMap layer.","scaleExtent":[0,19],"terms_url":"http://openstreetmap.org/","terms_text":"© OpenStreetMap contributors, CC-BY-SA","default":true},{"id":"osm-gps","name":"OpenStreetMap GPS traces","type":"tms","template":"http://{switch:a,b,c}.gps-tile.openstreetmap.org/lines/{zoom}/{x}/{y}.png","description":"Public GPS traces uploaded to OpenStreetMap.","scaleExtent":[0,20],"terms_url":"http://www.openstreetmap.org/copyright","terms_text":"© OpenStreetMap contributors","terms_html":"<span style='display: inline-block; padding: 0 8px; background-color: rgba(0,0,0,0.5);'><span style='color: #eee;'>GPS Direction:</span> <span style='font-size: 15px; padding-left: 2px; font-weight: bold;'> <span style='color: #0ee;'>←</span> <span style='color: #96f;'>↓</span> <span style='color: #6e0;'>↑</span> <span style='color: #f63;'>→</span> </span></span> © <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap contributors</a>.","overlay":true},{"id":"OS-historic-25k-OSM_Limited","name":"OS 1:25k historic (OSM)","type":"tms","template":"http://ooc.openstreetmap.org/os1/{zoom}/{x}/{y}.jpg","scaleExtent":[6,17],"polygon":[[[-9,49.8],[-9,61.1],[1.9,61.1],[1.9,49.8],[-9,49.8]]]},{"id":"OS-New_Popular_Edition-historic","name":"OS New Popular Edition historic","type":"tms","template":"http://ooc.openstreetmap.org/npe/{zoom}/{x}/{y}.png","polygon":[[[-5.8,49.8],[-5.8,55.8],[1.9,55.8],[1.9,49.8],[-5.8,49.8]]]},{"id":"OS-OpenData_Locator","name":"OS OpenData Locator","type":"tms","template":"http://tiles.itoworld.com/os_locator/{zoom}/{x}/{y}.png","polygon":[[[-9,49.8],[-9,61.1],[1.9,61.1],[1.9,49.8],[-9,49.8]]],"overlay":true},{"id":"OS-OpenData_StreetView","name":"OS OpenData StreetView","type":"tms","template":"http://os.openstreetmap.org/sv/{zoom}/{x}/{y}.png","scaleExtent":[1,18],"polygon":[[[-5.8292886,50.0229734],[-5.8292886,50.254819],[-5.373356,50.254819],[-5.373356,50.3530588],[-5.1756021,50.3530588],[-5.1756021,50.5925406],[-4.9970743,50.5925406],[-4.9970743,50.6935617],[-4.7965738,50.6935617],[-4.7965738,50.7822112],[-4.6949503,50.7822112],[-4.6949503,50.9607371],[-4.6043131,50.9607371],[-4.6043131,51.0692066],[-4.3792215,51.0692066],[-4.3792215,51.2521782],[-3.9039346,51.2521782],[-3.9039346,51.2916998],[-3.7171671,51.2916998],[-3.7171671,51.2453014],[-3.1486246,51.2453014],[-3.1486246,51.362067],[-3.7446329,51.362067],[-3.7446329,51.4340386],[-3.8297769,51.4340386],[-3.8297769,51.5298246],[-4.0852091,51.5298246],[-4.0852091,51.4939284],[-4.3792215,51.4939284],[-4.3792215,51.5427168],[-5.1444195,51.5427168],[-5.1444195,51.6296003],[-5.7387103,51.6296003],[-5.7387103,51.774037],[-5.5095393,51.774037],[-5.5095393,51.9802596],[-5.198799,51.9802596],[-5.198799,52.0973358],[-4.8880588,52.0973358],[-4.8880588,52.1831557],[-4.4957492,52.1831557],[-4.4957492,52.2925739],[-4.3015365,52.2925739],[-4.3015365,52.3685318],[-4.1811246,52.3685318],[-4.1811246,52.7933685],[-4.4413696,52.7933685],[-4.4413696,52.7369614],[-4.8569847,52.7369614],[-4.8569847,52.9317255],[-4.7288044,52.9317255],[-4.7288044,53.5038599],[-4.1578191,53.5038599],[-4.1578191,53.4113498],[-3.3110518,53.4113498],[-3.3110518,53.5038599],[-3.2333667,53.5038599],[-3.2333667,54.0159169],[-3.3926211,54.0159169],[-3.3926211,54.1980953],[-3.559644,54.1980953],[-3.559644,54.433732],[-3.7188984,54.433732],[-3.7188984,54.721897],[-4.3015365,54.721897],[-4.3015365,54.6140739],[-5.0473132,54.6140739],[-5.0473132,54.7532915],[-5.2298731,54.7532915],[-5.2298731,55.2190799],[-5.6532567,55.2190799],[-5.6532567,55.250088],[-5.8979647,55.250088],[-5.8979647,55.4822462],[-6.5933212,55.4822462],[-6.5933212,56.3013441],[-7.1727691,56.3013441],[-7.1727691,56.5601822],[-6.8171722,56.5601822],[-6.8171722,56.6991713],[-6.5315276,56.6991713],[-6.5315276,56.9066964],[-6.811679,56.9066964],[-6.811679,57.3716613],[-6.8721038,57.3716613],[-6.8721038,57.5518893],[-7.0973235,57.5518893],[-7.0973235,57.2411085],[-7.1742278,57.2411085],[-7.1742278,56.9066964],[-7.3719817,56.9066964],[-7.3719817,56.8075885],[-7.5202972,56.8075885],[-7.5202972,56.7142479],[-7.8306806,56.7142479],[-7.8306806,56.8994605],[-7.6494061,56.8994605],[-7.6494061,57.4739617],[-7.8306806,57.4739617],[-7.8306806,57.7915584],[-7.4736249,57.7915584],[-7.4736249,58.086063],[-7.1879804,58.086063],[-7.1879804,58.367197],[-6.8034589,58.367197],[-6.8034589,58.4155786],[-6.638664,58.4155786],[-6.638664,58.4673277],[-6.5178143,58.4673277],[-6.5178143,58.5625632],[-6.0536224,58.5625632],[-6.0536224,58.1568843],[-6.1470062,58.1568843],[-6.1470062,58.1105865],[-6.2799798,58.1105865],[-6.2799798,57.7122664],[-6.1591302,57.7122664],[-6.1591302,57.6667563],[-5.9339104,57.6667563],[-5.9339104,57.8892524],[-5.80643,57.8892524],[-5.80643,57.9621767],[-5.6141692,57.9621767],[-5.6141692,58.0911236],[-5.490819,58.0911236],[-5.490819,58.3733281],[-5.3199118,58.3733281],[-5.3199118,58.75015],[-3.5719977,58.75015],[-3.5719977,59.2091788],[-3.1944501,59.2091788],[-3.1944501,59.4759216],[-2.243583,59.4759216],[-2.243583,59.1388749],[-2.4611012,59.1388749],[-2.4611012,58.8185938],[-2.7407675,58.8185938],[-2.7407675,58.5804743],[-2.9116746,58.5804743],[-2.9116746,58.1157523],[-3.4865441,58.1157523],[-3.4865441,57.740386],[-1.7153245,57.740386],[-1.7153245,57.2225558],[-1.9794538,57.2225558],[-1.9794538,56.8760742],[-2.1658979,56.8760742],[-2.1658979,56.6333186],[-2.3601106,56.6333186],[-2.3601106,56.0477521],[-1.9794538,56.0477521],[-1.9794538,55.8650949],[-1.4745008,55.8650949],[-1.4745008,55.2499926],[-1.3221997,55.2499926],[-1.3221997,54.8221737],[-1.0550014,54.8221737],[-1.0550014,54.6746628],[-0.6618765,54.6746628],[-0.6618765,54.5527463],[-0.3247617,54.5527463],[-0.3247617,54.2865195],[0.0092841,54.2865195],[0.0092841,53.7938518],[0.2081962,53.7938518],[0.2081962,53.5217726],[0.4163548,53.5217726],[0.4163548,53.0298851],[1.4273388,53.0298851],[1.4273388,52.92021],[1.8333912,52.92021],[1.8333912,52.042488],[1.5235504,52.042488],[1.5235504,51.8261335],[1.2697049,51.8261335],[1.2697049,51.6967453],[1.116651,51.6967453],[1.116651,51.440346],[1.5235504,51.440346],[1.5235504,51.3331831],[1.4507565,51.3331831],[1.4507565,51.0207553],[1.0699883,51.0207553],[1.0699883,50.9008416],[0.7788126,50.9008416],[0.7788126,50.729843],[-0.7255952,50.729843],[-0.7255952,50.7038437],[-1.0074383,50.7038437],[-1.0074383,50.5736307],[-2.3625252,50.5736307],[-2.3625252,50.4846421],[-2.4987805,50.4846421],[-2.4987805,50.5736307],[-3.4096378,50.5736307],[-3.4096378,50.2057837],[-3.6922446,50.2057837],[-3.6922446,50.1347737],[-5.005468,50.1347737],[-5.005468,49.9474456],[-5.2839506,49.9474456],[-5.2839506,50.0229734],[-5.8292886,50.0229734]],[[-6.4580707,49.8673563],[-6.4580707,49.9499935],[-6.3978807,49.9499935],[-6.3978807,50.0053797],[-6.1799606,50.0053797],[-6.1799606,49.9168614],[-6.2540201,49.9168614],[-6.2540201,49.8673563],[-6.4580707,49.8673563]],[[-5.8343165,49.932156],[-5.8343165,49.9754641],[-5.7683254,49.9754641],[-5.7683254,49.932156],[-5.8343165,49.932156]],[[-1.9483797,60.6885737],[-1.9483797,60.3058841],[-1.7543149,60.3058841],[-1.7543149,60.1284428],[-1.5754914,60.1284428],[-1.5754914,59.797917],[-1.0316959,59.797917],[-1.0316959,60.0354518],[-0.6626918,60.0354518],[-0.6626918,60.9103862],[-1.1034395,60.9103862],[-1.1034395,60.8040022],[-1.3506319,60.8040022],[-1.3506319,60.6885737],[-1.9483797,60.6885737]],[[-2.203381,60.1968568],[-2.203381,60.0929443],[-1.9864011,60.0929443],[-1.9864011,60.1968568],[-2.203381,60.1968568]],[[-1.7543149,59.5698289],[-1.7543149,59.4639383],[-1.5373349,59.4639383],[-1.5373349,59.5698289],[-1.7543149,59.5698289]],[[-4.5585981,59.1370518],[-4.5585981,58.9569099],[-4.2867004,58.9569099],[-4.2867004,59.1370518],[-4.5585981,59.1370518]],[[-6.2787732,59.2025744],[-6.2787732,59.0227769],[-5.6650612,59.0227769],[-5.6650612,59.2025744],[-6.2787732,59.2025744]],[[-8.7163482,57.9440556],[-8.7163482,57.7305936],[-8.3592926,57.7305936],[-8.3592926,57.9440556],[-8.7163482,57.9440556]],[[-7.6077005,50.4021026],[-7.6077005,50.2688657],[-7.3907205,50.2688657],[-7.3907205,50.4021026],[-7.6077005,50.4021026]],[[-7.7304303,58.3579902],[-7.7304303,58.248313],[-7.5134503,58.248313],[-7.5134503,58.3579902],[-7.7304303,58.3579902]]]},{"id":"OS-Scottish_Popular-historic","name":"OS Scottish Popular historic","type":"tms","template":"http://ooc.openstreetmap.org/npescotland/tiles/{zoom}/{x}/{y}.jpg","scaleExtent":[6,15],"polygon":[[[-7.8,54.5],[-7.8,61.1],[-1.1,61.1],[-1.1,54.5],[-7.8,54.5]]]},{"id":"Pangasinan_Bulacan_HiRes","name":"Pangasinán/Bulacan (Phillipines HiRes)","type":"tms","template":"http://gravitystorm.dev.openstreetmap.org/imagery/philippines/{zoom}/{x}/{y}.png","scaleExtent":[12,19],"polygon":[[[120.336593,15.985768],[120.445995,15.984],[120.446134,15.974459],[120.476464,15.974592],[120.594247,15.946832],[120.598064,16.090795],[120.596537,16.197999],[120.368537,16.218527],[120.347576,16.042308],[120.336593,15.985768]],[[120.8268,15.3658],[121.2684,15.2602],[121.2699,14.7025],[120.695,14.8423],[120.8268,15.3658]]]},{"id":"PNOA-Spain-TMS","name":"PNOA Spain","type":"tms","template":"http://www.ign.es/wmts/pnoa-ma?request=GetTile&service=WMTS&VERSION=1.0.0&Layer=OI.OrthoimageCoverage&Style=default&Format=image/png&TileMatrixSet=GoogleMapsCompatible&TileMatrix={zoom}&TileRow={y}&TileCol={x}","polygon":[[[-17.8846298,28.4460601],[-17.8939535,28.5225529],[-18.0212548,28.7481927],[-18.0224091,28.8038375],[-17.9424017,28.8726124],[-17.8911792,28.8737099],[-17.8903302,28.8515102],[-17.7675902,28.8537764],[-17.7669837,28.8312183],[-17.7412714,28.8319975],[-17.7394926,28.7642235],[-17.7139824,28.7649677],[-17.7129312,28.7303731],[-17.7574427,28.6931782],[-17.7570788,28.6741254],[-17.7457913,28.6743524],[-17.7457266,28.6165627],[-17.7519687,28.5833675],[-17.7622536,28.5591958],[-17.7833086,28.541667],[-17.7831575,28.4936643],[-17.808611,28.4925024],[-17.8060072,28.4468974],[-17.8846298,28.4460601]],[[-18.1661033,27.7851643],[-18.163494,27.6949247],[-18.0889827,27.6963366],[-18.0873398,27.6738724],[-18.0364092,27.6753701],[-18.0350079,27.6302571],[-17.9589987,27.6323976],[-17.8603269,27.7926025],[-17.8630328,27.8368793],[-17.8884015,27.8364947],[-17.8891263,27.8590536],[-17.9906491,27.8567467],[-18.0386803,27.7655831],[-18.1146412,27.7637873],[-18.1154627,27.7863613],[-18.1661033,27.7851643]],[[-17.36038,28.0639801],[-17.3629657,28.1757247],[-17.3375583,28.1763688],[-17.3384577,28.2213012],[-17.1857883,28.2238767],[-17.0820788,28.1351849],[-17.0808422,28.0679977],[-17.1315446,28.0668073],[-17.1563337,28.0214628],[-17.2321063,28.0203711],[-17.2319938,27.9980388],[-17.2576823,27.9978403],[-17.257851,28.0199741],[-17.3086658,28.0192298],[-17.36038,28.0639801]],[[-16.9278171,28.3275779],[-16.9286591,28.3721879],[-16.8776666,28.3729288],[-16.8780707,28.3954191],[-16.5214259,28.4226146],[-16.4457117,28.491135],[-16.4462506,28.535972],[-16.4205859,28.5362679],[-16.4209227,28.5588419],[-16.3443329,28.5597589],[-16.3446023,28.5822095],[-16.1912541,28.5837179],[-16.1916246,28.6068435],[-16.1279344,28.6078193],[-16.1277997,28.5921762],[-16.0995079,28.5925015],[-16.0993395,28.5163822],[-16.1648148,28.5161158],[-16.1647474,28.4938583],[-16.2385755,28.4484704],[-16.2653516,28.4476116],[-16.2658569,28.4030038],[-16.3167484,28.4017594],[-16.3163105,28.380189],[-16.3420763,28.3795075],[-16.3408301,28.2892963],[-16.415837,28.1976134],[-16.415096,28.1311312],[-16.5153297,28.0164796],[-16.6168433,28.01532],[-16.6168096,27.9930469],[-16.7184243,27.9919168],[-16.7190979,28.0371426],[-16.7446952,28.0367859],[-16.7453351,28.0818146],[-16.7706967,28.0816065],[-16.8223966,28.1259036],[-16.8231712,28.1708652],[-16.8487012,28.1707464],[-16.8502842,28.260791],[-16.8756457,28.2605537],[-16.8760836,28.2832162],[-16.9015125,28.2827713],[-16.9023882,28.3279337],[-16.9278171,28.3275779]],[[-15.8537427,27.9008901],[-15.8542032,27.9901812],[-15.828953,27.9906555],[-15.8291065,28.035578],[-15.7782992,28.0363232],[-15.7532793,28.0814298],[-15.7278756,28.0815652],[-15.7282593,28.1718567],[-15.4989741,28.1728039],[-15.4987438,28.1504075],[-15.4497785,28.1507459],[-15.4501622,28.1961425],[-15.3972827,28.1961425],[-15.3964385,28.0383554],[-15.3710348,28.0380167],[-15.3706511,28.0153212],[-15.3457847,28.0153212],[-15.3454777,27.9254406],[-15.3708046,27.9252372],[-15.3705743,27.8352137],[-15.395978,27.8347387],[-15.4209979,27.7879673],[-15.4718052,27.7893932],[-15.471882,27.7666454],[-15.522766,27.7667813],[-15.5477092,27.7216112],[-15.6236132,27.7213395],[-15.6241504,27.741991],[-15.7007451,27.7433495],[-15.801669,27.8110501],[-15.8537427,27.9008901]],[[-14.5215621,28.0467778],[-14.5224358,28.1184131],[-14.4157526,28.1156076],[-14.2168794,28.2278805],[-14.2153651,28.33903],[-14.1641672,28.4528287],[-14.1115132,28.4747955],[-14.0335806,28.7226671],[-13.9565217,28.7449351],[-13.9561722,28.7665857],[-13.8290221,28.7664325],[-13.8289639,28.7879765],[-13.8000741,28.7879255],[-13.8012972,28.7189894],[-13.827566,28.719347],[-13.8278572,28.6517968],[-13.8025786,28.651899],[-13.8033941,28.5384172],[-13.8288474,28.5384684],[-13.8315061,28.3970177],[-13.9158189,28.2241438],[-13.9856445,28.2235696],[-14.0369588,28.1795787],[-14.1387139,28.1799894],[-14.1386556,28.1579103],[-14.2153651,28.1578076],[-14.2147244,28.1118888],[-14.2913173,28.0452356],[-14.3319673,28.0368713],[-14.4457846,28.0469834],[-14.4466583,28.0657961],[-14.4962835,28.0682631],[-14.495934,28.0458525],[-14.5215621,28.0467778]],[[-13.800662,28.8456579],[-13.8009273,28.8231121],[-13.775688,28.8230539],[-13.69729,28.8898184],[-13.69729,28.9127744],[-13.6072498,28.9117991],[-13.4388551,29.0002417],[-13.4374559,29.1351289],[-13.4117005,29.1349931],[-13.4105556,29.2229789],[-13.4592801,29.255586],[-13.4597392,29.2942023],[-13.5091254,29.2945638],[-13.5100581,29.3163453],[-13.5635382,29.3172941],[-13.5640564,29.2713764],[-13.5389228,29.2711956],[-13.5389747,29.2500375],[-13.5661293,29.2501279],[-13.5665956,29.2030039],[-13.5156549,29.2022349],[-13.5156549,29.1820579],[-13.5398038,29.1827819],[-13.5408921,29.137528],[-13.65782,29.1368528],[-13.713222,29.0935079],[-13.7663353,29.0934533],[-13.8502463,29.0165937],[-13.8518224,28.983425],[-13.8524443,28.914861],[-13.9013122,28.89245],[-13.9024005,28.8469779],[-13.800662,28.8456579]],[[1.6479916,38.9990693],[1.7321668,38.9993635],[1.7314703,39.0441733],[1.6489512,39.0431944],[1.6481552,39.1276358],[1.3948608,39.1265691],[1.3954412,39.0864199],[1.2281145,39.0852615],[1.2291095,39.0028958],[1.1448657,39.0018003],[1.1452803,38.8319988],[1.3113632,38.8331615],[1.3121924,38.7906483],[1.3946949,38.7916178],[1.3951924,38.7529597],[1.3112803,38.7519251],[1.3125919,38.6238804],[1.6489036,38.6251112],[1.6480745,38.7111504],[1.58456,38.7101152],[1.5811604,38.7005387],[1.5491544,38.7002798],[1.5197188,38.7092094],[1.50355,38.7253185],[1.4813282,38.9155064],[1.5518906,38.9254411],[1.5667328,38.9566554],[1.6487378,38.9583318],[1.6479916,38.9990693]],[[2.5450749,39.4166673],[2.43933,39.4161122],[2.438714,39.4846853],[2.439022,39.4993424],[2.3122308,39.4993424],[2.3119228,39.5417911],[2.2290722,39.5409994],[2.2283536,39.6260571],[2.3460076,39.6270851],[2.9270445,39.9601558],[3.1456647,39.9600498],[3.1460753,40.0019797],[3.2313899,40.0019797],[3.2312872,39.8329231],[3.1482313,39.8331596],[3.1484366,39.7935717],[3.4814817,39.7931773],[3.4803472,39.5959027],[3.3150618,39.4784606],[3.3146179,39.3785504],[3.0830178,39.2499355],[2.9798608,39.2501482],[2.9790395,39.3334971],[2.7287424,39.3334177],[2.7288451,39.4581361],[2.6456865,39.4577397],[2.6453785,39.4996593],[2.5452802,39.4994216],[2.5450749,39.4166673]],[[3.8120402,40.0434431],[3.729082,40.0437979],[3.7286185,39.9584155],[3.8126633,39.9576011],[3.8122771,39.9164393],[3.9608975,39.9159813],[4.1938142,39.791308],[4.3150279,39.7905799],[4.3159934,39.8329294],[4.3987393,39.8320396],[4.3973664,39.9185834],[4.3158003,39.9193274],[4.3161865,40.0433985],[4.2318959,40.0443594],[4.2324752,40.0847793],[4.1491501,40.086109],[4.1490623,40.1255157],[4.0627981,40.1272166],[4.0624217,40.0849941],[3.8128687,40.085294],[3.8120402,40.0434431]],[[-8.8910646,41.8228891],[-9.1092038,42.5751065],[-9.0365469,42.730656],[-9.0883419,42.7269569],[-9.1466113,42.7750272],[-9.2185488,42.9016271],[-9.2760988,42.8605106],[-9.3099094,42.9311297],[-9.2789763,42.9821991],[-9.3099094,43.0600377],[-9.2523594,43.1041725],[-9.2314975,43.1703151],[-9.1473307,43.210176],[-9.06748,43.1991644],[-9.0336694,43.2426748],[-8.99842,43.2447709],[-8.9998588,43.2955793],[-8.9372732,43.3055265],[-8.92936,43.326986],[-8.8638969,43.3290792],[-8.8761263,43.3740655],[-8.8221732,43.3735426],[-8.785485,43.3191358],[-8.7063538,43.305003],[-8.6099575,43.3296025],[-8.5509688,43.3233227],[-8.5243519,43.3364048],[-8.5250713,43.3646525],[-8.45745,43.3918416],[-8.3610538,43.4111803],[-8.3603344,43.4634161],[-8.3344369,43.5797394],[-8.2776063,43.5708796],[-8.0646713,43.7239184],[-7.9992081,43.7233986],[-7.9171994,43.7826357],[-7.8560525,43.7914643],[-7.83591,43.7374337],[-7.6628443,43.809819],[-7.3188932,43.6782695],[-7.1997467,43.5830817],[-6.2488228,43.6075032],[-6.1229322,43.5790105],[-5.8520425,43.6798953],[-5.6036334,43.5708672],[-5.2855347,43.5619084],[-5.1787525,43.4991591],[-4.9089869,43.4836655],[-4.6156167,43.4192021],[-4.1839917,43.4249168],[-3.8029478,43.5195394],[-3.7400025,43.4869277],[-3.5612827,43.5423572],[-3.1083013,43.3816347],[-2.9385737,43.4624573],[-2.7452417,43.4755094],[-2.3046245,43.3170625],[-1.9854018,43.3563045],[-1.8552841,43.3972545],[-1.769802,43.3964383],[-1.7700492,43.3760501],[-1.7100474,43.3756908],[-1.7113451,43.3312527],[-1.7225915,43.3131806],[-1.6890375,43.3129108],[-1.6881106,43.3341294],[-1.6446695,43.3337248],[-1.6449785,43.3133155],[-1.6029903,43.3129528],[-1.6034352,43.2926624],[-1.5635905,43.2921227],[-1.5630468,43.3133844],[-1.4779905,43.3128355],[-1.3667723,43.2761368],[-1.3568809,43.2381533],[-1.3703692,43.1712972],[-1.4423067,43.0833554],[-1.4198262,43.0603647],[-1.3730668,43.051166],[-1.3640746,43.1115893],[-1.3020285,43.135217],[-1.2354864,43.1332484],[-1.2795481,43.0774443],[-1.1923239,43.0649635],[-1.0061856,43.0077821],[-0.942341,42.9748951],[-0.7562028,42.9821318],[-0.7148387,42.9610774],[-0.6968543,42.9031405],[-0.5511809,42.8220693],[-0.5044215,42.8484456],[-0.4288871,42.8200906],[-0.3164848,42.8655842],[-0.1456332,42.810856],[-0.0314324,42.7124874],[0.1861785,42.7540985],[0.3021777,42.7177729],[0.3642238,42.7428729],[0.4487504,42.7144695],[0.6276949,42.7223973],[0.6411832,42.8576747],[0.7149192,42.882718],[0.9675996,42.8181119],[1.108777,42.7989808],[1.1753192,42.7342872],[1.3632559,42.7415521],[1.4113736,42.7093914],[1.4806054,42.7103407],[1.4813006,42.5010664],[1.6443591,42.5020345],[1.6432777,42.5424539],[1.730407,42.5434214],[1.7316429,42.5011803],[2.0638621,42.5016359],[2.0645572,42.4590247],[2.3969309,42.4599364],[2.3976786,42.4178363],[2.4804823,42.4179732],[2.4809767,42.3759441],[2.6447922,42.3762636],[2.6444832,42.4592447],[2.8113266,42.4596094],[2.8112648,42.5010358],[3.063878,42.5008535],[3.063878,42.4591535],[3.2307832,42.4593359],[3.2304935,42.3764363],[3.3141469,42.3760369],[3.3141243,42.3339864],[3.397855,42.3340435],[3.3973912,42.290094],[3.3138923,42.2908368],[3.3139695,42.2070151],[3.1475896,42.2073012],[3.1475896,42.1260612],[3.2305478,42.1260039],[3.2466753,41.9529359],[3.1945206,41.8558943],[3.060537,41.7647419],[2.7835777,41.6371796],[2.26293,41.4271601],[2.1649151,41.2989297],[1.86008,41.2232228],[1.3763003,41.116273],[1.1793714,41.0464585],[1.0858526,41.048493],[0.758537,40.8195599],[0.9114042,40.733761],[0.8781331,40.6751363],[0.6650182,40.5358666],[0.5580112,40.5502166],[0.433919,40.3757589],[0.2675635,40.1919192],[0.1641534,40.0647234],[0.0751307,40.0144671],[0.010387,39.8952188],[-0.0939224,39.8116904],[-0.1847435,39.6311716],[-0.2908513,39.5036254],[-0.2863552,39.333431],[-0.1856427,39.1774612],[-0.2135185,39.1558487],[-0.1110076,38.9722246],[0.0094878,38.8826835],[0.1218901,38.872183],[0.2342925,38.798636],[0.2558737,38.7264162],[0.0958128,38.6133825],[-0.0022021,38.6070586],[-0.0570544,38.5269073],[-0.2719677,38.4762395],[-0.379874,38.3931234],[-0.3834708,38.3381297],[-0.4509122,38.3310763],[-0.5048654,38.2830943],[-0.4823849,38.1948095],[-0.429331,38.1658287],[-0.4545091,38.148859],[-0.5839966,38.1721913],[-0.6136708,38.1198599],[-0.6370505,37.9612228],[-0.6811123,37.9456238],[-0.7323677,37.8810656],[-0.7215771,37.7830562],[-0.688306,37.7340026],[-0.6641461,37.6231485],[-0.7193941,37.5878413],[-0.9196258,37.5375806],[-1.1107098,37.5164093],[-1.3383246,37.5286671],[-1.4408917,37.3903714],[-1.6766966,37.2765189],[-1.8540816,36.9122889],[-2.0683486,36.6929117],[-2.2158766,36.6619233],[-2.3721861,36.7801753],[-2.6812926,36.6591056],[-2.9201476,36.6675585],[-3.09402,36.712625],[-3.4610839,36.6548788],[-3.7280395,36.6929117],[-4.3743529,36.6633322],[-4.6571151,36.4404171],[-4.9188018,36.4531321],[-5.1699508,36.3513541],[-5.2841094,36.1970201],[-5.2680911,36.1241812],[-5.3524784,36.1224654],[-5.3516094,36.0401413],[-5.4365759,36.0388921],[-5.4353207,36.0034384],[-5.6888562,36.0036518],[-5.6899635,36.0405317],[-5.85506,36.0385595],[-5.8566821,36.1242077],[-5.9384817,36.1221487],[-5.9400265,36.1655625],[-5.9983445,36.1645024],[-6.0357297,36.1780957],[-6.0775178,36.2224132],[-6.1506113,36.2864561],[-6.231541,36.3770075],[-6.3358504,36.5310643],[-6.3214629,36.5816265],[-6.404191,36.6234958],[-6.4743301,36.7489673],[-6.4158808,36.7993866],[-6.490516,36.9173818],[-6.6298949,37.0194012],[-6.8744824,37.1083766],[-7.0426363,37.1850699],[-7.2647434,37.1843535],[-7.3753473,37.1535419],[-7.408316,37.1682196],[-7.4202886,37.2118318],[-7.4249231,37.2350505],[-7.4380543,37.2451969],[-7.4459717,37.3326142],[-7.4480958,37.3909382],[-7.4696271,37.4075829],[-7.4647029,37.4530494],[-7.5019723,37.516411],[-7.5191587,37.5229203],[-7.5219588,37.5723727],[-7.4501271,37.6695835],[-7.4249019,37.7599222],[-7.316662,37.839974],[-7.268329,37.988952],[-7.1536786,38.0155235],[-7.1177098,38.0553626],[-7.0142997,38.0243785],[-6.9963153,38.1075633],[-6.9614706,38.201254],[-7.080617,38.1570753],[-7.3402665,38.4402363],[-7.2638329,38.7380741],[-7.0435243,38.8729667],[-7.0615086,38.907962],[-6.9693387,39.0198308],[-7.0008114,39.0887867],[-7.1536786,39.0957658],[-7.1525545,39.1602899],[-7.2447245,39.1968854],[-7.2559647,39.2813308],[-7.3368944,39.3535074],[-7.3279022,39.4559917],[-7.5144901,39.5886496],[-7.5527069,39.6795427],[-7.0502684,39.6752171],[-6.9951913,39.8195433],[-6.9221297,39.8790868],[-6.886161,40.0229854],[-7.0412762,40.1347927],[-7.0176717,40.266146],[-6.8086034,40.3450071],[-6.8681766,40.4451649],[-6.8535643,40.6066433],[-6.837828,40.8757589],[-6.9536024,41.0370445],[-6.8018592,41.0395879],[-6.7681385,41.138706],[-6.6411239,41.2655616],[-6.5624422,41.2630269],[-6.217367,41.5791017],[-6.3162811,41.644652],[-6.5152332,41.6412921],[-6.5871707,41.6883151],[-6.5478299,41.8559743],[-6.6298836,41.9112057],[-7.1334461,41.9404756],[-7.1682909,41.8718791],[-7.4256922,41.7847727],[-7.9539833,41.8459271],[-8.130455,41.7805819],[-8.2518495,41.9078597],[-8.1293309,42.0348842],[-8.2484774,42.1008034],[-8.3676239,42.0557521],[-8.6070409,42.0340493],[-8.8910646,41.8228891]]],"terms_text":"PNOA"},{"id":"Slovakia-Historic-Maps","name":"Slovakia Historic Maps","type":"tms","template":"http://tms.freemap.sk/historicke/{zoom}/{x}/{y}.png","scaleExtent":[0,12],"polygon":[[[16.8196949,47.4927236],[16.8196949,49.5030322],[22.8388318,49.5030322],[22.8388318,47.4927236],[16.8196949,47.4927236]]]},{"id":"South_Africa-CD_NGI-Aerial","name":"South Africa CD:NGI Aerial","type":"tms","template":"http://{switch:a,b,c}.aerial.openstreetmap.org.za/ngi-aerial/{zoom}/{x}/{y}.jpg","scaleExtent":[1,22],"polygon":[[[17.8396817,-32.7983384],[17.8893509,-32.6972835],[18.00364,-32.6982187],[18.0991679,-32.7485251],[18.2898747,-32.5526645],[18.2930182,-32.0487089],[18.105455,-31.6454966],[17.8529257,-31.3443951],[17.5480046,-30.902171],[17.4044506,-30.6374731],[17.2493704,-30.3991663],[16.9936977,-29.6543552],[16.7987996,-29.19437],[16.5494139,-28.8415949],[16.4498691,-28.691876],[16.4491046,-28.5515766],[16.6002551,-28.4825663],[16.7514057,-28.4486958],[16.7462192,-28.2458973],[16.8855148,-28.04729],[16.9929502,-28.0244005],[17.0529659,-28.0257086],[17.1007562,-28.0338839],[17.2011527,-28.0930546],[17.2026346,-28.2328424],[17.2474611,-28.2338215],[17.2507953,-28.198892],[17.3511919,-28.1975861],[17.3515624,-28.2442655],[17.4015754,-28.2452446],[17.4149122,-28.3489751],[17.4008345,-28.547997],[17.4526999,-28.5489733],[17.4512071,-28.6495106],[17.4983599,-28.6872054],[17.6028204,-28.6830048],[17.6499732,-28.6967928],[17.6525928,-28.7381457],[17.801386,-28.7381457],[17.9994276,-28.7560602],[18.0002748,-28.7956172],[18.1574507,-28.8718055],[18.5063811,-28.8718055],[18.6153564,-28.8295875],[18.9087513,-28.8277516],[19.1046973,-28.9488548],[19.1969071,-28.9378513],[19.243012,-28.8516164],[19.2314858,-28.802963],[19.2587296,-28.7009928],[19.4431493,-28.6973163],[19.5500289,-28.4958332],[19.6967264,-28.4939914],[19.698822,-28.4479358],[19.8507587,-28.4433291],[19.8497109,-28.4027818],[19.9953605,-28.399095],[19.9893671,-24.7497859],[20.2916682,-24.9192346],[20.4724562,-25.1501701],[20.6532441,-25.4529449],[20.733265,-25.6801957],[20.8281046,-25.8963498],[20.8429232,-26.215851],[20.6502804,-26.4840868],[20.6532441,-26.8204869],[21.0889134,-26.846933],[21.6727695,-26.8389998],[21.7765003,-26.6696268],[21.9721069,-26.6431395],[22.2803355,-26.3274702],[22.5707817,-26.1333967],[22.7752795,-25.6775246],[23.0005235,-25.2761948],[23.4658301,-25.2735148],[23.883717,-25.597366],[24.2364017,-25.613402],[24.603905,-25.7896563],[25.110704,-25.7389432],[25.5078447,-25.6855376],[25.6441766,-25.4823781],[25.8419267,-24.7805437],[25.846641,-24.7538456],[26.3928487,-24.6332894],[26.4739066,-24.5653312],[26.5089966,-24.4842437],[26.5861946,-24.4075775],[26.7300635,-24.3014458],[26.8567384,-24.2499463],[26.8574402,-24.1026901],[26.9215471,-23.8990957],[26.931831,-23.8461891],[26.9714827,-23.6994344],[27.0006074,-23.6367644],[27.0578041,-23.6052574],[27.1360547,-23.5203437],[27.3339623,-23.3973792],[27.5144057,-23.3593929],[27.5958145,-23.2085465],[27.8098634,-23.0994957],[27.8828506,-23.0620496],[27.9382928,-22.9496487],[28.0407556,-22.8255118],[28.2056786,-22.6552861],[28.3397223,-22.5639374],[28.4906093,-22.560697],[28.6108769,-22.5400248],[28.828175,-22.4550173],[28.9285324,-22.4232328],[28.9594116,-22.3090081],[29.0162574,-22.208335],[29.2324117,-22.1693453],[29.3531213,-22.1842926],[29.6548952,-22.1186426],[29.7777102,-22.1361956],[29.9292989,-22.1849425],[30.1166795,-22.2830348],[30.2563377,-22.2914767],[30.3033582,-22.3395204],[30.5061784,-22.3057617],[30.8374279,-22.284983],[31.0058599,-22.3077095],[31.1834152,-22.3232913],[31.2930586,-22.3674647],[31.5680579,-23.1903385],[31.5568311,-23.4430809],[31.6931122,-23.6175209],[31.7119696,-23.741136],[31.7774743,-23.8800628],[31.8886337,-23.9481098],[31.9144386,-24.1746736],[31.9948307,-24.3040878],[32.0166656,-24.4405988],[32.0077331,-24.6536578],[32.019643,-24.9140701],[32.035523,-25.0849767],[32.019643,-25.3821442],[31.9928457,-25.4493771],[31.9997931,-25.5165725],[32.0057481,-25.6078978],[32.0057481,-25.6624806],[31.9362735,-25.8403721],[31.9809357,-25.9546537],[31.8687838,-26.0037251],[31.4162062,-25.7277683],[31.3229117,-25.7438611],[31.2504595,-25.8296526],[31.1393001,-25.9162746],[31.1164727,-25.9912361],[30.9656135,-26.2665756],[30.8921689,-26.3279703],[30.8534616,-26.4035568],[30.8226943,-26.4488849],[30.8022583,-26.5240694],[30.8038369,-26.8082089],[30.9020939,-26.7807451],[30.9100338,-26.8489495],[30.9824859,-26.9082627],[30.976531,-27.0029222],[31.0034434,-27.0441587],[31.1543322,-27.1980416],[31.5015607,-27.311117],[31.9700183,-27.311117],[31.9700183,-27.120472],[31.9769658,-27.050664],[32.0002464,-26.7983892],[32.1069826,-26.7984645],[32.3114546,-26.8479493],[32.899986,-26.8516059],[32.886091,-26.9816971],[32.709427,-27.4785436],[32.6240724,-27.7775144],[32.5813951,-28.07479],[32.5387178,-28.2288046],[32.4275584,-28.5021568],[32.3640388,-28.5945699],[32.0702603,-28.8469827],[31.9878832,-28.9069497],[31.7764818,-28.969487],[31.4638459,-29.2859343],[31.359634,-29.3854348],[31.1680825,-29.6307408],[31.064863,-29.7893535],[31.0534493,-29.8470469],[31.0669933,-29.8640319],[31.0455459,-29.9502017],[30.9518556,-30.0033946],[30.8651833,-30.1024093],[30.7244725,-30.392502],[30.3556256,-30.9308873],[30.0972364,-31.2458274],[29.8673136,-31.4304296],[29.7409393,-31.5014699],[29.481312,-31.6978686],[28.8943171,-32.2898903],[28.5497137,-32.5894641],[28.1436499,-32.8320732],[28.0748735,-32.941689],[27.8450942,-33.082869],[27.3757956,-33.3860685],[26.8805407,-33.6458951],[26.5916871,-33.7480756],[26.4527308,-33.7935795],[26.206754,-33.7548943],[26.0077897,-33.7223961],[25.8055494,-33.7524272],[25.7511073,-33.8006512],[25.6529079,-33.8543597],[25.6529079,-33.9469768],[25.7195789,-34.0040115],[25.7202807,-34.0511235],[25.5508915,-34.063151],[25.3504571,-34.0502627],[25.2810609,-34.0020322],[25.0476316,-33.9994588],[24.954724,-34.0043594],[24.9496586,-34.1010363],[24.8770358,-34.1506456],[24.8762914,-34.2005281],[24.8532574,-34.2189562],[24.7645287,-34.2017946],[24.5001356,-34.2003254],[24.3486733,-34.1163824],[24.1988819,-34.1019039],[23.9963377,-34.0514443],[23.8017509,-34.0524332],[23.7493589,-34.0111855],[23.4973536,-34.009014],[23.4155191,-34.0434586],[23.4154284,-34.1140433],[22.9000853,-34.0993009],[22.8412418,-34.0547911],[22.6470321,-34.0502627],[22.6459843,-34.0072768],[22.570016,-34.0064081],[22.5050499,-34.0645866],[22.2519968,-34.0645866],[22.2221334,-34.1014701],[22.1621197,-34.1057019],[22.1712431,-34.1521766],[22.1576913,-34.2180897],[22.0015632,-34.2172232],[21.9496952,-34.3220009],[21.8611528,-34.4007145],[21.5614708,-34.4020114],[21.5468011,-34.3661242],[21.501744,-34.3669892],[21.5006961,-34.4020114],[21.4194886,-34.4465247],[21.1978706,-34.4478208],[21.0988193,-34.3991325],[21.0033746,-34.3753872],[20.893192,-34.3997115],[20.8976647,-34.4854003],[20.7446802,-34.4828092],[20.5042011,-34.486264],[20.2527197,-34.701477],[20.0803502,-34.8361855],[19.9923317,-34.8379056],[19.899074,-34.8275845],[19.8938348,-34.7936018],[19.5972963,-34.7961833],[19.3929677,-34.642015],[19.2877095,-34.6404784],[19.2861377,-34.5986563],[19.3474363,-34.5244458],[19.3285256,-34.4534372],[19.098001,-34.449981],[19.0725583,-34.3802371],[19.0023531,-34.3525593],[18.9520568,-34.3949373],[18.7975006,-34.3936403],[18.7984174,-34.1016376],[18.501748,-34.1015292],[18.4999545,-34.3616945],[18.4477325,-34.3620007],[18.4479944,-34.3522691],[18.3974362,-34.3514041],[18.3971742,-34.3022959],[18.3565705,-34.3005647],[18.3479258,-34.2020436],[18.2972095,-34.1950274],[18.2951139,-33.9937138],[18.3374474,-33.9914079],[18.3476638,-33.8492427],[18.3479258,-33.781555],[18.4124718,-33.7448849],[18.3615477,-33.6501624],[18.2992013,-33.585591],[18.2166839,-33.448872],[18.1389858,-33.3974083],[17.9473472,-33.1602647],[17.8855247,-33.0575732],[17.8485884,-32.9668505],[17.8396817,-32.8507302],[17.8396817,-32.7983384]]],"best":true},{"id":"South-Tyrol-Orthofoto2011","name":"South Tyrol Orthofoto 2011","type":"tms","template":"http://geoservices.buergernetz.bz.it/geoserver/gwc/service/wmts/?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=P_BZ_OF_2011_EPSG3857&STYLE=default&TILEMATRIXSET=GoogleMapsCompatible&TILEMATRIX=GoogleMapsCompatible%3A{zoom}&TILEROW={y}&TILECOL={x}&FORMAT=image%2Fjpeg","description":"Orthophoto of South Tyrol from 2011","scaleExtent":[0,18],"polygon":[[[10.38615,46.68821],[10.39201,46.69016],[10.40215,46.70624],[10.41274,46.70821],[10.41622,46.71479],[10.4168,46.71847],[10.39934,46.73435],[10.43464,46.75356],[10.44107,46.75413],[10.44011,46.77149],[10.42123,46.78861],[10.42845,46.79755],[10.43851,46.79869],[10.44925,46.80462],[10.45602,46.81635],[10.45438,46.82221],[10.4583,46.82478],[10.45513,46.83059],[10.45906,46.83548],[10.46483,46.83624],[10.46229,46.8413],[10.46987,46.84933],[10.46819,46.8553],[10.47838,46.86013],[10.48372,46.85543],[10.49628,46.85305],[10.49931,46.84857],[10.52124,46.84653],[10.5527,46.8511],[10.55795,46.84695],[10.55264,46.8408],[10.55536,46.84087],[10.58883,46.85125],[10.59502,46.85829],[10.60936,46.8597],[10.62441,46.86558],[10.64858,46.86655],[10.66787,46.87651],[10.67297,46.87138],[10.69112,46.86861],[10.69786,46.86339],[10.69508,46.85308],[10.70594,46.84786],[10.71763,46.84795],[10.72333,46.83892],[10.75621,46.83383],[10.76481,46.82409],[10.76387,46.81971],[10.75239,46.81387],[10.74506,46.80223],[10.7276,46.79709],[10.73122,46.78925],[10.75722,46.78624],[10.77744,46.79149],[10.78678,46.79735],[10.81439,46.77662],[10.82479,46.77472],[10.83129,46.78138],[10.84112,46.78282],[10.85354,46.77506],[10.86845,46.77313],[10.86993,46.7669],[10.88294,46.76393],[10.88962,46.76529],[10.8951,46.77092],[10.90527,46.76911],[10.92299,46.7764],[10.92821,46.77408],[10.94388,46.77648],[10.97522,46.77361],[10.97932,46.77014],[10.99475,46.76804],[11.01397,46.77317],[11.02328,46.76715],[11.0346,46.79428],[11.04234,46.801],[11.03792,46.80562],[11.05633,46.80928],[11.07279,46.82092],[11.08171,46.82252],[11.0762,46.83384],[11.06887,46.83793],[11.07303,46.84345],[11.06988,46.85348],[11.08742,46.87927],[11.09961,46.88922],[11.09538,46.89178],[11.09795,46.89844],[11.0946,46.91247],[11.10792,46.91706],[11.10804,46.92632],[11.11418,46.93234],[11.13851,46.92865],[11.16322,46.94091],[11.16642,46.94479],[11.16114,46.94979],[11.1637,46.96677],[11.17598,46.96367],[11.18658,46.97062],[11.19527,46.97152],[11.20418,46.96877],[11.20688,46.96403],[11.22047,46.97025],[11.24139,46.9708],[11.24865,46.97517],[11.25582,46.97535],[11.26272,46.98169],[11.27662,46.98168],[11.28762,46.98699],[11.30709,46.98525],[11.3205,46.99345],[11.33765,46.98606],[11.34516,46.99169],[11.35932,46.99154],[11.37697,46.98025],[11.38324,46.97168],[11.40465,46.96609],[11.43929,46.97601],[11.45134,46.99294],[11.46803,46.99582],[11.46859,47.003],[11.47831,47.01201],[11.50238,47.01073],[11.50313,47.00808],[11.51366,47.00595],[11.51679,47.00091],[11.53381,46.99233],[11.53846,46.98519],[11.55297,46.99149],[11.57663,46.99657],[11.58,47.00277],[11.58879,47.00641],[11.59901,47.00657],[11.60944,47.01207],[11.62697,47.01437],[11.63629,47.00383],[11.66542,46.99304],[11.6885,46.99658],[11.71226,46.99416],[11.72897,46.97322],[11.74698,46.97013],[11.76411,46.97412],[11.78106,46.99342],[11.81526,46.991],[11.83564,46.99417],[11.84396,47.0025],[11.85192,47.0014],[11.86722,47.01252],[11.87393,47.01136],[11.8794,47.01714],[11.89137,47.01728],[11.91627,47.03422],[11.9329,47.03864],[11.94688,47.03464],[11.95457,47.04374],[11.96773,47.04158],[11.97912,47.0511],[11.98587,47.04815],[11.99534,47.05064],[12.02037,47.04821],[12.02968,47.05127],[12.03353,47.0583],[12.04276,47.06228],[12.07543,47.0605],[12.08035,47.06951],[12.09308,47.07791],[12.10329,47.07931],[12.11867,47.07445],[12.13561,47.08171],[12.15125,47.08049],[12.15997,47.08267],[12.18589,47.09322],[12.2278,47.08302],[12.24228,47.06892],[12.23786,47.0644],[12.21821,47.05795],[12.2182,47.04483],[12.20552,47.02595],[12.18048,47.02414],[12.16423,47.01782],[12.14786,47.02357],[12.12723,47.01218],[12.12285,47.00662],[12.1322,46.99339],[12.12974,46.98593],[12.13977,46.982],[12.13808,46.96514],[12.13328,46.96292],[12.13882,46.95764],[12.15927,46.95133],[12.1702,46.93758],[12.15414,46.91654],[12.14675,46.91413],[12.16205,46.908],[12.16959,46.91121],[12.19154,46.90682],[12.20106,46.8965],[12.2022,46.88806],[12.21663,46.87517],[12.22147,46.88084],[12.23125,46.88146],[12.2345,46.88919],[12.24162,46.89192],[12.27486,46.88512],[12.27979,46.87921],[12.27736,46.87319],[12.29326,46.86566],[12.2912,46.85704],[12.29733,46.84455],[12.30833,46.84137],[12.30726,46.83271],[12.285,46.81503],[12.29383,46.8027],[12.28905,46.79948],[12.28889,46.79427],[12.28232,46.79153],[12.28539,46.7839],[12.30943,46.78603],[12.35837,46.77583],[12.37036,46.74163],[12.38475,46.71745],[12.40283,46.70811],[12.41103,46.70701],[12.41522,46.70163],[12.42862,46.6997],[12.42943,46.69567],[12.44268,46.68979],[12.47501,46.68756],[12.4795,46.67969],[12.43473,46.66714],[12.40648,46.64167],[12.38115,46.64183],[12.37944,46.63733],[12.3915,46.62765],[12.38577,46.62154],[12.35939,46.61829],[12.34465,46.62376],[12.34034,46.63022],[12.33578,46.62732],[12.3172,46.62876],[12.31785,46.62355],[12.30802,46.61811],[12.28413,46.61623],[12.26982,46.62003],[12.25931,46.62809],[12.24502,46.62326],[12.24198,46.61586],[12.21241,46.60918],[12.20444,46.59836],[12.19228,46.59321],[12.19261,46.62059],[12.1818,46.6192],[12.17117,46.63275],[12.16062,46.63574],[12.1511,46.63215],[12.1436,46.6327],[12.13739,46.64122],[12.12342,46.64475],[12.10949,46.65204],[12.10609,46.65783],[12.09345,46.66123],[12.08826,46.66638],[12.07985,46.66686],[12.07038,46.67386],[12.07173,46.66064],[12.06686,46.65364],[12.07479,46.64329],[12.06837,46.63997],[12.06495,46.62121],[12.05448,46.61778],[12.05318,46.60989],[12.04613,46.60716],[12.05043,46.60016],[12.04763,46.58357],[12.03665,46.57668],[12.0266,46.55871],[12.02189,46.55791],[11.99941,46.53208],[11.99411,46.53345],[11.98704,46.54417],[11.96633,46.54363],[11.95094,46.53869],[11.94719,46.52879],[11.94147,46.52689],[11.93294,46.52631],[11.9121,46.532],[11.8904,46.52175],[11.85192,46.51682],[11.82849,46.50783],[11.82334,46.51315],[11.82391,46.52141],[11.81086,46.53146],[11.79385,46.52023],[11.79189,46.51322],[11.76157,46.50503],[11.74317,46.50391],[11.73202,46.50877],[11.71935,46.50916],[11.71524,46.51245],[11.69889,46.50218],[11.6672,46.49647],[11.64515,46.49743],[11.63849,46.50051],[11.63495,46.49486],[11.64297,46.49346],[11.65174,46.48271],[11.64536,46.47189],[11.64179,46.47439],[11.62679,46.4708],[11.62987,46.46377],[11.61882,46.44325],[11.62143,46.42539],[11.60161,46.39731],[11.60307,46.38924],[11.5932,46.38265],[11.56489,46.38018],[11.55878,46.35076],[11.55249,46.34418],[11.54423,46.34483],[11.53837,46.35015],[11.52445,46.35502],[11.47969,46.36277],[11.48052,46.3551],[11.46322,46.34922],[11.45556,46.33396],[11.42105,46.32441],[11.40517,46.32387],[11.39865,46.31426],[11.39994,46.30709],[11.39569,46.3083],[11.38188,46.30052],[11.36088,46.29906],[11.36078,46.29682],[11.38256,46.29177],[11.3871,46.28143],[11.39609,46.27423],[11.39862,46.264],[11.38756,46.26029],[11.37347,46.2629],[11.36836,46.26135],[11.35783,46.26481],[11.35495,46.27564],[11.33912,46.28306],[11.33379,46.29049],[11.33471,46.2962],[11.3129,46.28256],[11.31737,46.27303],[11.30645,46.25786],[11.29124,46.2604],[11.24743,46.22933],[11.20622,46.2187],[11.18267,46.22496],[11.17077,46.23806],[11.17994,46.24434],[11.18351,46.25269],[11.18935,46.25354],[11.19448,46.2461],[11.20029,46.25566],[11.16604,46.26129],[11.14885,46.27904],[11.13725,46.28336],[11.14293,46.28934],[11.15847,46.29059],[11.16439,46.2986],[11.1761,46.30346],[11.1847,46.32104],[11.18894,46.32151],[11.18696,46.32673],[11.1942,46.33016],[11.20204,46.34212],[11.19001,46.35984],[11.19263,46.36578],[11.20393,46.36765],[11.19792,46.37232],[11.21275,46.39804],[11.21345,46.40675],[11.20565,46.4166],[11.21026,46.4206],[11.20347,46.42682],[11.21416,46.43556],[11.21634,46.44255],[11.20903,46.45293],[11.21419,46.45807],[11.21736,46.45731],[11.21886,46.46199],[11.21626,46.47277],[11.20939,46.481],[11.20876,46.49346],[11.19608,46.50241],[11.1924,46.501],[11.18686,46.50734],[11.18002,46.49823],[11.17014,46.49635],[11.16095,46.4878],[11.12934,46.48058],[11.1103,46.49643],[11.10449,46.4948],[11.08812,46.50128],[11.08173,46.53021],[11.05915,46.51508],[11.03795,46.51357],[11.05006,46.50784],[11.05773,46.49235],[11.06278,46.4894],[11.06894,46.46619],[11.07625,46.45487],[11.0778,46.44569],[11.07301,46.44042],[11.05394,46.44849],[11.0414,46.44569],[11.02817,46.46116],[11.00952,46.46917],[11.00462,46.47607],[10.98695,46.48289],[10.96543,46.48103],[10.95791,46.46983],[10.93819,46.46578],[10.9325,46.45831],[10.93332,46.4528],[10.91305,46.44284],[10.89161,46.44366],[10.88324,46.44995],[10.88093,46.44579],[10.87162,46.4438],[10.86174,46.43509],[10.85113,46.43817],[10.80034,46.44185],[10.78906,46.45164],[10.77835,46.47112],[10.76934,46.47609],[10.76463,46.4848],[10.75906,46.48547],[10.74422,46.48333],[10.71753,46.46022],[10.69667,46.4573],[10.68293,46.44846],[10.66821,46.45122],[10.63303,46.44309],[10.61439,46.45098],[10.60128,46.46139],[10.59995,46.46766],[10.57672,46.47237],[10.55875,46.48187],[10.54986,46.49123],[10.53685,46.49062],[10.52657,46.49425],[10.49366,46.49719],[10.48141,46.49337],[10.45714,46.5096],[10.45124,46.53083],[10.45814,46.54215],[10.47056,46.54377],[10.46954,46.54856],[10.47617,46.55749],[10.47321,46.56701],[10.48305,46.5777],[10.48575,46.58921],[10.48221,46.59199],[10.48576,46.59805],[10.48291,46.60512],[10.49055,46.61394],[10.44632,46.63989],[10.40935,46.63389],[10.40011,46.63648],[10.39873,46.6455],[10.38946,46.65862],[10.39057,46.67089],[10.3803,46.68399],[10.38615,46.68821]]],"terms_url":"http://geoservices.buergernetz.bz.it/geokatalog/","terms_text":"© Autonomen Provinz Bozen/Provincia Autonoma di Bolzano CC-BY 3.0"},{"id":"South-Tyrol-Orthofoto2014","name":"South Tyrol Orthofoto 2014","type":"tms","template":"http://geoservices.buergernetz.bz.it/geoserver/gwc/service/wmts/?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=P_BZ_OF_2014_EPSG3857&STYLE=default&TILEMATRIXSET=GoogleMapsCompatible&TILEMATRIX=GoogleMapsCompatible%3A{zoom}&TILEROW={y}&TILECOL={x}&FORMAT=image%2Fjpeg","description":"Orthophoto of South Tyrol from 2011","scaleExtent":[0,18],"polygon":[[[12.23442,46.84254],[12.24913,46.82785],[12.24913,46.81945],[12.25753,46.81735],[12.26173,46.80686],[12.26594,46.80686],[12.26804,46.79637],[12.26173,46.79427],[12.27014,46.78587],[12.27224,46.76908],[12.28485,46.76698],[12.29745,46.7439],[12.30166,46.7439],[12.30166,46.7376],[12.28695,46.7376],[12.23652,46.72081],[12.18819,46.71451],[12.16298,46.70192],[12.10835,46.69353],[12.08944,46.68303],[12.05792,46.68093],[12.04531,46.67464],[12.03481,46.67464],[12.03061,46.68303],[12.0096,46.68303],[11.98438,46.66834],[11.94866,46.66414],[11.93816,46.65575],[11.90874,46.64525],[11.89193,46.64525],[11.8457,46.62846],[11.82049,46.62636],[11.80998,46.60748],[11.79528,46.60328],[11.78897,46.59069],[11.78057,46.58859],[11.76586,46.55501],[11.75325,46.54871],[11.73855,46.52982],[11.73224,46.52982],[11.72384,46.51513],[11.71543,46.51513],[11.71333,46.50254],[11.70913,46.50254],[11.70913,46.49624],[11.69652,46.48575],[11.69442,46.47735],[11.66711,46.47525],[11.66711,46.44587],[11.6608,46.44587],[11.64399,46.45846],[11.63769,46.45846],[11.63349,46.44587],[11.62508,46.44797],[11.62508,46.43957],[11.61878,46.43957],[11.61458,46.42278],[11.61037,46.42278],[11.61037,46.41649],[11.62508,46.41229],[11.62508,46.3934],[11.61458,46.38291],[11.60617,46.38291],[11.60407,46.37241],[11.58306,46.37241],[11.58306,46.34932],[11.55995,46.32414],[11.53894,46.32834],[11.53894,46.34513],[11.52423,46.34723],[11.50111,46.34723],[11.49901,46.32834],[11.48851,46.33044],[11.49271,46.32204],[11.41917,46.32414],[11.41707,46.25278],[11.35613,46.24858],[11.34773,46.25698],[11.34563,46.26747],[11.34143,46.26747],[11.33722,46.25068],[11.31201,46.24858],[11.30991,46.25278],[11.3015,46.25278],[11.2889,46.24019],[11.2889,46.2234],[11.25108,46.2234],[11.24898,46.2129],[11.16283,46.215],[11.16283,46.24858],[11.12711,46.24858],[11.13131,46.25278],[11.12291,46.25488],[11.12501,46.29895],[11.16283,46.29895],[11.16283,46.36821],[11.16703,46.36821],[11.16703,46.38081],[11.17543,46.3871],[11.17754,46.3997],[11.20485,46.3997],[11.20695,46.42068],[11.19014,46.42068],[11.19014,46.42698],[11.19435,46.42698],[11.19855,46.44167],[11.20485,46.44587],[11.20695,46.47315],[11.19014,46.47525],[11.18804,46.48365],[11.15232,46.47525],[11.08298,46.47525],[11.08088,46.43537],[11.04096,46.42068],[11.01154,46.42068],[10.99894,46.44587],[10.98843,46.44587],[10.98423,46.45217],[10.96952,46.45217],[10.96112,46.48365],[10.95691,46.48365],[10.95481,46.49414],[10.94851,46.49624],[10.94431,46.50673],[10.91069,46.49624],[10.90018,46.49624],[10.89808,46.51093],[10.85606,46.50254],[10.84135,46.54241],[10.86446,46.54661],[10.86236,46.55081],[10.76571,46.54031],[10.72158,46.55081],[10.59762,46.55291],[10.5619,46.54871],[10.53668,46.55291],[10.50096,46.54871],[10.48415,46.55501],[10.46314,46.55501],[10.47155,46.5676],[10.47365,46.59069],[10.47785,46.59069],[10.47785,46.61797],[10.46944,46.62636],[10.44843,46.63476],[10.42532,46.62846],[10.3938,46.63056],[10.3896,46.64525],[10.3812,46.64735],[10.3833,46.66414],[10.3791,46.66834],[10.3791,46.69353],[10.3854,46.72081],[10.3896,46.72081],[10.3938,46.7376],[10.41692,46.75229],[10.41692,46.78587],[10.42112,46.79847],[10.42532,46.79847],[10.42532,46.80686],[10.43373,46.81106],[10.43793,46.79007],[10.44423,46.78377],[10.44843,46.7439],[10.45264,46.7439],[10.45684,46.72711],[10.46104,46.72711],[10.46524,46.71032],[10.46944,46.71032],[10.47365,46.67254],[10.47995,46.67044],[10.48415,46.65575],[10.48836,46.65575],[10.48415,46.62846],[10.48836,46.62846],[10.48836,46.62217],[10.49886,46.62007],[10.52828,46.62427],[10.49886,46.63056],[10.49886,46.64525],[10.50516,46.64316],[10.49886,46.66204],[10.51777,46.65785],[10.58921,46.66204],[10.63123,46.65365],[10.79302,46.65575],[10.79723,46.65155],[10.88127,46.65155],[10.89178,46.65785],[10.9275,46.66414],[10.94431,46.67464],[10.98003,46.67464],[11.00104,46.68303],[11.02415,46.68303],[11.05147,46.69772],[11.12711,46.70822],[11.13971,46.71242],[11.14392,46.71871],[11.17543,46.72081],[11.19855,46.7334],[11.24898,46.7355],[11.25318,46.72291],[11.2952,46.72921],[11.30571,46.70822],[11.31831,46.70822],[11.33722,46.71871],[11.38555,46.72081],[11.43178,46.7376],[11.50952,46.7439],[11.54734,46.75649],[11.56835,46.75649],[11.58306,46.76698],[11.60617,46.76908],[11.61037,46.77538],[11.69862,46.79427],[11.71753,46.79427],[11.72174,46.79007],[11.73855,46.75859],[11.74905,46.75019],[11.76166,46.70192],[11.76586,46.70192],[11.78687,46.71661],[11.8331,46.72291],[11.86041,46.7376],[11.90874,46.7439],[11.92135,46.75229],[11.95286,46.75859],[11.95917,46.76488],[11.99489,46.77538],[12.00749,46.77538],[12.0096,46.77958],[12.03061,46.78168],[12.05792,46.79427],[12.09995,46.79847],[12.13566,46.81316],[12.15878,46.81316],[12.18609,46.82785],[12.21551,46.83205],[12.23442,46.84254]],[[11.97388,46.96637],[11.99489,46.96007],[11.99489,46.95587],[12.0096,46.95797],[12.0117,46.94748],[12.0159,46.94748],[12.0117,46.94118],[12.018,46.93908],[12.02851,46.92229],[12.00749,46.9118],[11.97388,46.9055],[11.95707,46.89501],[11.91714,46.88871],[11.85831,46.86982],[11.8394,46.86982],[11.80158,46.85303],[11.76166,46.84464],[11.74905,46.83415],[11.68181,46.81945],[11.67971,46.81526],[11.6545,46.81106],[11.64399,46.80476],[11.63769,46.80686],[11.63139,46.82155],[11.62508,46.82155],[11.62298,46.83205],[11.61037,46.84464],[11.61668,46.84884],[11.61458,46.85723],[11.61037,46.85723],[11.61668,46.86563],[11.64609,46.86563],[11.68602,46.88242],[11.69022,46.88871],[11.74905,46.89711],[11.75325,46.90341],[11.78057,46.9076],[11.80158,46.9202],[11.8457,46.92649],[11.87722,46.94118],[11.89613,46.94328],[11.92135,46.95797],[11.96757,46.96217],[11.97388,46.96637]]],"terms_url":"http://geoservices.buergernetz.bz.it/geokatalog/","terms_text":"© Autonomen Provinz Bozen/Provincia Autonoma di Bolzano CC-BY 3.0","best":true},{"id":"South-Tyrol-Topomap","name":"South Tyrol Topomap","type":"tms","template":"http://geoservices.buergernetz.bz.it/geoserver/gwc/service/wmts/?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=P_BZ_BASEMAP_TOPO&STYLE=default&TILEMATRIXSET=GoogleMapsCompatible&TILEMATRIX=GoogleMapsCompatible%3A{zoom}&TILEROW={y}&TILECOL={x}&FORMAT=image%2Fjpeg","description":"Topographical basemap of South Tyrol","scaleExtent":[0,20],"polygon":[[[10.38615,46.68821],[10.39201,46.69016],[10.40215,46.70624],[10.41274,46.70821],[10.41622,46.71479],[10.4168,46.71847],[10.39934,46.73435],[10.43464,46.75356],[10.44107,46.75413],[10.44011,46.77149],[10.42123,46.78861],[10.42845,46.79755],[10.43851,46.79869],[10.44925,46.80462],[10.45602,46.81635],[10.45438,46.82221],[10.4583,46.82478],[10.45513,46.83059],[10.45906,46.83548],[10.46483,46.83624],[10.46229,46.8413],[10.46987,46.84933],[10.46819,46.8553],[10.47838,46.86013],[10.48372,46.85543],[10.49628,46.85305],[10.49931,46.84857],[10.52124,46.84653],[10.5527,46.8511],[10.55795,46.84695],[10.55264,46.8408],[10.55536,46.84087],[10.58883,46.85125],[10.59502,46.85829],[10.60936,46.8597],[10.62441,46.86558],[10.64858,46.86655],[10.66787,46.87651],[10.67297,46.87138],[10.69112,46.86861],[10.69786,46.86339],[10.69508,46.85308],[10.70594,46.84786],[10.71763,46.84795],[10.72333,46.83892],[10.75621,46.83383],[10.76481,46.82409],[10.76387,46.81971],[10.75239,46.81387],[10.74506,46.80223],[10.7276,46.79709],[10.73122,46.78925],[10.75722,46.78624],[10.77744,46.79149],[10.78678,46.79735],[10.81439,46.77662],[10.82479,46.77472],[10.83129,46.78138],[10.84112,46.78282],[10.85354,46.77506],[10.86845,46.77313],[10.86993,46.7669],[10.88294,46.76393],[10.88962,46.76529],[10.8951,46.77092],[10.90527,46.76911],[10.92299,46.7764],[10.92821,46.77408],[10.94388,46.77648],[10.97522,46.77361],[10.97932,46.77014],[10.99475,46.76804],[11.01397,46.77317],[11.02328,46.76715],[11.0346,46.79428],[11.04234,46.801],[11.03792,46.80562],[11.05633,46.80928],[11.07279,46.82092],[11.08171,46.82252],[11.0762,46.83384],[11.06887,46.83793],[11.07303,46.84345],[11.06988,46.85348],[11.08742,46.87927],[11.09961,46.88922],[11.09538,46.89178],[11.09795,46.89844],[11.0946,46.91247],[11.10792,46.91706],[11.10804,46.92632],[11.11418,46.93234],[11.13851,46.92865],[11.16322,46.94091],[11.16642,46.94479],[11.16114,46.94979],[11.1637,46.96677],[11.17598,46.96367],[11.18658,46.97062],[11.19527,46.97152],[11.20418,46.96877],[11.20688,46.96403],[11.22047,46.97025],[11.24139,46.9708],[11.24865,46.97517],[11.25582,46.97535],[11.26272,46.98169],[11.27662,46.98168],[11.28762,46.98699],[11.30709,46.98525],[11.3205,46.99345],[11.33765,46.98606],[11.34516,46.99169],[11.35932,46.99154],[11.37697,46.98025],[11.38324,46.97168],[11.40465,46.96609],[11.43929,46.97601],[11.45134,46.99294],[11.46803,46.99582],[11.46859,47.003],[11.47831,47.01201],[11.50238,47.01073],[11.50313,47.00808],[11.51366,47.00595],[11.51679,47.00091],[11.53381,46.99233],[11.53846,46.98519],[11.55297,46.99149],[11.57663,46.99657],[11.58,47.00277],[11.58879,47.00641],[11.59901,47.00657],[11.60944,47.01207],[11.62697,47.01437],[11.63629,47.00383],[11.66542,46.99304],[11.6885,46.99658],[11.71226,46.99416],[11.72897,46.97322],[11.74698,46.97013],[11.76411,46.97412],[11.78106,46.99342],[11.81526,46.991],[11.83564,46.99417],[11.84396,47.0025],[11.85192,47.0014],[11.86722,47.01252],[11.87393,47.01136],[11.8794,47.01714],[11.89137,47.01728],[11.91627,47.03422],[11.9329,47.03864],[11.94688,47.03464],[11.95457,47.04374],[11.96773,47.04158],[11.97912,47.0511],[11.98587,47.04815],[11.99534,47.05064],[12.02037,47.04821],[12.02968,47.05127],[12.03353,47.0583],[12.04276,47.06228],[12.07543,47.0605],[12.08035,47.06951],[12.09308,47.07791],[12.10329,47.07931],[12.11867,47.07445],[12.13561,47.08171],[12.15125,47.08049],[12.15997,47.08267],[12.18589,47.09322],[12.2278,47.08302],[12.24228,47.06892],[12.23786,47.0644],[12.21821,47.05795],[12.2182,47.04483],[12.20552,47.02595],[12.18048,47.02414],[12.16423,47.01782],[12.14786,47.02357],[12.12723,47.01218],[12.12285,47.00662],[12.1322,46.99339],[12.12974,46.98593],[12.13977,46.982],[12.13808,46.96514],[12.13328,46.96292],[12.13882,46.95764],[12.15927,46.95133],[12.1702,46.93758],[12.15414,46.91654],[12.14675,46.91413],[12.16205,46.908],[12.16959,46.91121],[12.19154,46.90682],[12.20106,46.8965],[12.2022,46.88806],[12.21663,46.87517],[12.22147,46.88084],[12.23125,46.88146],[12.2345,46.88919],[12.24162,46.89192],[12.27486,46.88512],[12.27979,46.87921],[12.27736,46.87319],[12.29326,46.86566],[12.2912,46.85704],[12.29733,46.84455],[12.30833,46.84137],[12.30726,46.83271],[12.285,46.81503],[12.29383,46.8027],[12.28905,46.79948],[12.28889,46.79427],[12.28232,46.79153],[12.28539,46.7839],[12.30943,46.78603],[12.35837,46.77583],[12.37036,46.74163],[12.38475,46.71745],[12.40283,46.70811],[12.41103,46.70701],[12.41522,46.70163],[12.42862,46.6997],[12.42943,46.69567],[12.44268,46.68979],[12.47501,46.68756],[12.4795,46.67969],[12.43473,46.66714],[12.40648,46.64167],[12.38115,46.64183],[12.37944,46.63733],[12.3915,46.62765],[12.38577,46.62154],[12.35939,46.61829],[12.34465,46.62376],[12.34034,46.63022],[12.33578,46.62732],[12.3172,46.62876],[12.31785,46.62355],[12.30802,46.61811],[12.28413,46.61623],[12.26982,46.62003],[12.25931,46.62809],[12.24502,46.62326],[12.24198,46.61586],[12.21241,46.60918],[12.20444,46.59836],[12.19228,46.59321],[12.19261,46.62059],[12.1818,46.6192],[12.17117,46.63275],[12.16062,46.63574],[12.1511,46.63215],[12.1436,46.6327],[12.13739,46.64122],[12.12342,46.64475],[12.10949,46.65204],[12.10609,46.65783],[12.09345,46.66123],[12.08826,46.66638],[12.07985,46.66686],[12.07038,46.67386],[12.07173,46.66064],[12.06686,46.65364],[12.07479,46.64329],[12.06837,46.63997],[12.06495,46.62121],[12.05448,46.61778],[12.05318,46.60989],[12.04613,46.60716],[12.05043,46.60016],[12.04763,46.58357],[12.03665,46.57668],[12.0266,46.55871],[12.02189,46.55791],[11.99941,46.53208],[11.99411,46.53345],[11.98704,46.54417],[11.96633,46.54363],[11.95094,46.53869],[11.94719,46.52879],[11.94147,46.52689],[11.93294,46.52631],[11.9121,46.532],[11.8904,46.52175],[11.85192,46.51682],[11.82849,46.50783],[11.82334,46.51315],[11.82391,46.52141],[11.81086,46.53146],[11.79385,46.52023],[11.79189,46.51322],[11.76157,46.50503],[11.74317,46.50391],[11.73202,46.50877],[11.71935,46.50916],[11.71524,46.51245],[11.69889,46.50218],[11.6672,46.49647],[11.64515,46.49743],[11.63849,46.50051],[11.63495,46.49486],[11.64297,46.49346],[11.65174,46.48271],[11.64536,46.47189],[11.64179,46.47439],[11.62679,46.4708],[11.62987,46.46377],[11.61882,46.44325],[11.62143,46.42539],[11.60161,46.39731],[11.60307,46.38924],[11.5932,46.38265],[11.56489,46.38018],[11.55878,46.35076],[11.55249,46.34418],[11.54423,46.34483],[11.53837,46.35015],[11.52445,46.35502],[11.47969,46.36277],[11.48052,46.3551],[11.46322,46.34922],[11.45556,46.33396],[11.42105,46.32441],[11.40517,46.32387],[11.39865,46.31426],[11.39994,46.30709],[11.39569,46.3083],[11.38188,46.30052],[11.36088,46.29906],[11.36078,46.29682],[11.38256,46.29177],[11.3871,46.28143],[11.39609,46.27423],[11.39862,46.264],[11.38756,46.26029],[11.37347,46.2629],[11.36836,46.26135],[11.35783,46.26481],[11.35495,46.27564],[11.33912,46.28306],[11.33379,46.29049],[11.33471,46.2962],[11.3129,46.28256],[11.31737,46.27303],[11.30645,46.25786],[11.29124,46.2604],[11.24743,46.22933],[11.20622,46.2187],[11.18267,46.22496],[11.17077,46.23806],[11.17994,46.24434],[11.18351,46.25269],[11.18935,46.25354],[11.19448,46.2461],[11.20029,46.25566],[11.16604,46.26129],[11.14885,46.27904],[11.13725,46.28336],[11.14293,46.28934],[11.15847,46.29059],[11.16439,46.2986],[11.1761,46.30346],[11.1847,46.32104],[11.18894,46.32151],[11.18696,46.32673],[11.1942,46.33016],[11.20204,46.34212],[11.19001,46.35984],[11.19263,46.36578],[11.20393,46.36765],[11.19792,46.37232],[11.21275,46.39804],[11.21345,46.40675],[11.20565,46.4166],[11.21026,46.4206],[11.20347,46.42682],[11.21416,46.43556],[11.21634,46.44255],[11.20903,46.45293],[11.21419,46.45807],[11.21736,46.45731],[11.21886,46.46199],[11.21626,46.47277],[11.20939,46.481],[11.20876,46.49346],[11.19608,46.50241],[11.1924,46.501],[11.18686,46.50734],[11.18002,46.49823],[11.17014,46.49635],[11.16095,46.4878],[11.12934,46.48058],[11.1103,46.49643],[11.10449,46.4948],[11.08812,46.50128],[11.08173,46.53021],[11.05915,46.51508],[11.03795,46.51357],[11.05006,46.50784],[11.05773,46.49235],[11.06278,46.4894],[11.06894,46.46619],[11.07625,46.45487],[11.0778,46.44569],[11.07301,46.44042],[11.05394,46.44849],[11.0414,46.44569],[11.02817,46.46116],[11.00952,46.46917],[11.00462,46.47607],[10.98695,46.48289],[10.96543,46.48103],[10.95791,46.46983],[10.93819,46.46578],[10.9325,46.45831],[10.93332,46.4528],[10.91305,46.44284],[10.89161,46.44366],[10.88324,46.44995],[10.88093,46.44579],[10.87162,46.4438],[10.86174,46.43509],[10.85113,46.43817],[10.80034,46.44185],[10.78906,46.45164],[10.77835,46.47112],[10.76934,46.47609],[10.76463,46.4848],[10.75906,46.48547],[10.74422,46.48333],[10.71753,46.46022],[10.69667,46.4573],[10.68293,46.44846],[10.66821,46.45122],[10.63303,46.44309],[10.61439,46.45098],[10.60128,46.46139],[10.59995,46.46766],[10.57672,46.47237],[10.55875,46.48187],[10.54986,46.49123],[10.53685,46.49062],[10.52657,46.49425],[10.49366,46.49719],[10.48141,46.49337],[10.45714,46.5096],[10.45124,46.53083],[10.45814,46.54215],[10.47056,46.54377],[10.46954,46.54856],[10.47617,46.55749],[10.47321,46.56701],[10.48305,46.5777],[10.48575,46.58921],[10.48221,46.59199],[10.48576,46.59805],[10.48291,46.60512],[10.49055,46.61394],[10.44632,46.63989],[10.40935,46.63389],[10.40011,46.63648],[10.39873,46.6455],[10.38946,46.65862],[10.39057,46.67089],[10.3803,46.68399],[10.38615,46.68821]]],"terms_url":"http://geoservices.buergernetz.bz.it/geokatalog/","terms_text":"© Autonomen Provinz Bozen/Provincia Autonoma di Bolzano"},{"id":"Bern-bern2016-tms","name":"Stadt Bern 10cm (2016)","type":"tms","template":"http://mapproxy.osm.ch:8080/tiles/bern2016/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","scaleExtent":[8,21],"polygon":[[[7.2943145,46.9237564],[7.2982665,46.9274715],[7.3061586,46.9309487],[7.3043338,46.9362344],[7.3068603,46.9403709],[7.3246431,46.9432765],[7.3284525,46.946409],[7.3414051,46.9460797],[7.3438454,46.9473713],[7.3434554,46.9487937],[7.3513567,46.9485481],[7.3505628,46.950213],[7.3530901,46.9519266],[7.3582028,46.9511773],[7.3685031,46.9566244],[7.3715097,46.9607339],[7.37503,46.959835],[7.3785111,46.9614686],[7.3806232,46.9654741],[7.3832097,46.9663014],[7.3937998,46.9669268],[7.4000528,46.9691779],[7.4082922,46.9686857],[7.4281713,46.9738041],[7.4327053,46.972689],[7.4353602,46.9684345],[7.4378522,46.9684302],[7.4412474,46.9767865],[7.4456893,46.9747939],[7.4483835,46.9756393],[7.4477006,46.9790125],[7.4440468,46.9780682],[7.4412738,46.9798224],[7.4506732,46.9901527],[7.4522112,46.9896803],[7.454649,46.9778182],[7.4680382,46.9758258],[7.4707923,46.969998],[7.4701907,46.9674116],[7.4781618,46.9711823],[7.4845237,46.9701571],[7.4861275,46.9679018],[7.4857945,46.9646828],[7.4784708,46.9629043],[7.4802865,46.9606768],[7.4789304,46.9587841],[7.4797786,46.9566019],[7.4770135,46.9544586],[7.4840504,46.9499938],[7.4833925,46.9451977],[7.4955563,46.9396169],[7.4935119,46.9376594],[7.4908036,46.9387617],[7.4894997,46.9368667],[7.4766667,46.9369496],[7.4781093,46.9362489],[7.4746986,46.9339187],[7.4753537,46.9329898],[7.4691047,46.9292427],[7.4707683,46.9255044],[7.4585674,46.934836],[7.4476373,46.9304297],[7.435418,46.9349668],[7.4338022,46.9331237],[7.4376403,46.9307415],[7.4146941,46.9368183],[7.413844,46.9315682],[7.4070798,46.9303824],[7.408065,46.9256296],[7.4021268,46.9241992],[7.4014835,46.9211927],[7.3875736,46.9304506],[7.3823129,46.927282],[7.3800187,46.9298929],[7.3808694,46.9324085],[7.3748669,46.9314306],[7.3748901,46.9327104],[7.368066,46.9323929],[7.3683058,46.930426],[7.3604074,46.9285884],[7.3605592,46.9272018],[7.338783,46.9245357],[7.3393683,46.9196675],[7.3274574,46.9190326],[7.3269178,46.9235974],[7.324374,46.9251891],[7.3082264,46.9222857],[7.2943145,46.9237564]]],"terms_text":"Orthophoto 2016, Vermessungsamt Stadt Bern ","best":true},{"id":"Uster-2008","name":"Stadt Uster Orthophoto 2008 10cm","type":"tms","template":"http://mapproxy.sosm.ch:8080/tiles/uster/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","polygon":[[[8.6,47.31],[8.6,47.39],[8.77,47.39],[8.77,47.31],[8.6,47.31]]],"terms_text":"Stadt Uster Vermessung Orthophoto 2008"},{"id":"Zuerich-zh_luftbild2011-tms","name":"Stadt Zürich Luftbild 2011","type":"tms","template":"http://mapproxy.sosm.ch:8080/tiles/zh_luftbild2011/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","polygon":[[[8.4441,47.3141],[8.4441,47.4411],[8.6284,47.4411],[8.6284,47.3141],[8.4441,47.3141]]],"terms_text":"Stadt Zürich Luftbild 2011"},{"id":"Zuerich-city_map","name":"Stadtplan Zürich","type":"tms","template":"http://mapproxy.sosm.ch:8080/tiles/zh_stadtplan/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","polygon":[[[8.4482,47.321],[8.4482,47.4339],[8.6248,47.4339],[8.6248,47.321],[8.4482,47.321]]],"terms_text":"Stadt Zürich Open Government Data"},{"id":"stamen-terrain-background","name":"Stamen Terrain","type":"tms","template":"http://{switch:a,b,c,d}.tile.stamen.com/terrain-background/{zoom}/{x}/{y}.jpg","scaleExtent":[4,18],"terms_url":"http://maps.stamen.com/#terrain","terms_text":"Map tiles by Stamen Design, under CC BY 3.0"},{"id":"Stevns_Denmark","name":"Stevns (Denmark)","type":"tms","template":"http://{switch:a,b,c}.tile.openstreetmap.dk/stevns/2009/{zoom}/{x}/{y}.png","scaleExtent":[0,20],"polygon":[[[12.0913942,55.3491574],[12.0943104,55.3842256],[12.1573875,55.3833103],[12.1587287,55.4013326],[12.1903468,55.400558],[12.1931411,55.4364665],[12.2564251,55.4347995],[12.2547073,55.4168882],[12.3822489,55.4134349],[12.3795942,55.3954143],[12.4109213,55.3946958],[12.409403,55.3766417],[12.4407807,55.375779],[12.4394142,55.3578314],[12.4707413,55.3569971],[12.4629475,55.2672214],[12.4315633,55.2681491],[12.430045,55.2502103],[12.3672011,55.2519673],[12.3656858,55.2340267],[12.2714604,55.2366031],[12.2744467,55.272476],[12.2115654,55.2741475],[12.2130078,55.2920322],[12.1815665,55.2928638],[12.183141,55.3107091],[12.2144897,55.3100981],[12.2159927,55.3279764],[12.1214458,55.3303379],[12.1229489,55.3483291],[12.0913942,55.3491574]]],"terms_text":"Stevns Kommune"},{"id":"Surrey-Air_Survey","name":"Surrey Air Survey","type":"tms","template":"http://gravitystorm.dev.openstreetmap.org/surrey/{zoom}/{x}/{y}.png","scaleExtent":[8,19],"polygon":[[[-0.752478,51.0821941],[-0.7595183,51.0856254],[-0.8014342,51.1457917],[-0.8398864,51.1440686],[-0.8357665,51.1802397],[-0.8529549,51.2011266],[-0.8522683,51.2096231],[-0.8495217,51.217903],[-0.8266907,51.2403696],[-0.8120995,51.2469248],[-0.7736474,51.2459577],[-0.7544213,51.2381127],[-0.754078,51.233921],[-0.7446366,51.2333836],[-0.7430693,51.2847178],[-0.751503,51.3069524],[-0.7664376,51.3121032],[-0.7820588,51.3270157],[-0.7815438,51.3388135],[-0.7374268,51.3720456],[-0.7192307,51.3769748],[-0.6795769,51.3847961],[-0.6807786,51.3901523],[-0.6531411,51.3917591],[-0.6301385,51.3905808],[-0.6291085,51.3970074],[-0.6234437,51.3977572],[-0.613144,51.4295552],[-0.6002471,51.4459121],[-0.5867081,51.4445365],[-0.5762368,51.453202],[-0.5626755,51.4523462],[-0.547741,51.4469972],[-0.5372697,51.4448575],[-0.537098,51.4526671],[-0.5439644,51.4545926],[-0.5405312,51.4698865],[-0.5309182,51.4760881],[-0.5091172,51.4744843],[-0.5086022,51.4695657],[-0.4900628,51.4682825],[-0.4526406,51.4606894],[-0.4486924,51.4429316],[-0.4414826,51.4418616],[-0.4418259,51.4369394],[-0.4112702,51.4380095],[-0.4014855,51.4279498],[-0.3807145,51.4262372],[-0.3805428,51.4161749],[-0.3491288,51.4138195],[-0.3274994,51.4037544],[-0.3039818,51.3990424],[-0.3019219,51.3754747],[-0.309475,51.369688],[-0.3111916,51.3529669],[-0.2955704,51.3541462],[-0.2923089,51.3673303],[-0.2850991,51.3680805],[-0.2787476,51.3771891],[-0.2655297,51.3837247],[-0.2411538,51.3847961],[-0.2123147,51.3628288],[-0.2107697,51.3498578],[-0.190857,51.3502867],[-0.1542931,51.3338802],[-0.1496583,51.3057719],[-0.1074296,51.2966491],[-0.0887185,51.3099571],[-0.0878602,51.3220811],[-0.0652009,51.3215448],[-0.0641709,51.3264793],[-0.0519829,51.3263721],[-0.0528412,51.334631],[-0.0330779,51.3430876],[0.0019187,51.3376339],[0.0118751,51.3281956],[0.013935,51.2994398],[0.0202865,51.2994398],[0.0240631,51.3072743],[0.0331611,51.3086694],[0.0455207,51.30545],[0.0523872,51.2877392],[0.0616569,51.2577764],[0.0640602,51.2415518],[0.0462074,51.2126342],[0.0407142,51.2109136],[0.0448341,51.1989753],[0.0494689,51.1997283],[0.0558204,51.1944573],[0.0611419,51.1790713],[0.0623435,51.1542061],[0.0577087,51.1417146],[0.0204582,51.1365447],[-0.0446015,51.1336364],[-0.1566964,51.1352522],[-0.1572114,51.1290043],[-0.2287942,51.1183379],[-0.2473336,51.1183379],[-0.2500802,51.1211394],[-0.299347,51.1137042],[-0.3221779,51.1119799],[-0.3223496,51.1058367],[-0.3596001,51.1019563],[-0.3589135,51.1113333],[-0.3863793,51.1117644],[-0.3869014,51.1062516],[-0.4281001,51.0947174],[-0.4856784,51.0951554],[-0.487135,51.0872266],[-0.5297404,51.0865404],[-0.5302259,51.0789914],[-0.61046,51.076551],[-0.6099745,51.080669],[-0.6577994,51.0792202],[-0.6582849,51.0743394],[-0.6836539,51.0707547],[-0.6997979,51.070831],[-0.7296581,51.0744919],[-0.752478,51.0821941]]]},{"id":"Szeged_2011","name":"Szeged ortophoto 2011","type":"tms","template":"http://e.tile.openstreetmap.hu/szeged-2011-10cm/{zoom}/{x}/{y}.png","scaleExtent":[10,22],"polygon":[[[20.1459914,46.2281144],[20.1332261,46.2290431],[20.1258373,46.2298686],[20.122329,46.2309893],[20.1208484,46.2317537],[20.1189709,46.2335126],[20.1131237,46.2413638],[20.1120293,46.2433005],[20.1115733,46.2449996],[20.1111871,46.247092],[20.1112944,46.2487725],[20.1115948,46.2509686],[20.1122171,46.2528047],[20.1129949,46.2542681],[20.1135421,46.2553549],[20.1147705,46.2567977],[20.1352251,46.2768529],[20.1366386,46.2775055],[20.1378939,46.2780301],[20.1393932,46.2783508],[20.1408818,46.2784583],[20.1611494,46.278159],[20.1621093,46.2781579],[20.1635894,46.277702],[20.1661777,46.2761484],[20.1687795,46.2738569],[20.1696108,46.2714413],[20.1695895,46.2704465],[20.1700871,46.2704418],[20.1739897,46.2643295],[20.1766182,46.2582878],[20.1947983,46.25492],[20.1858719,46.2448077],[20.1846595,46.2453122],[20.1780371,46.2383112],[20.1781766,46.2377101],[20.1795258,46.2370961],[20.1725666,46.2300241],[20.1698349,46.2350404],[20.1687701,46.2362946],[20.1670262,46.2378475],[20.1659431,46.2387342],[20.1654408,46.2389988],[20.1654837,46.2389988],[20.1635177,46.2401383],[20.1602051,46.2412003],[20.1592684,46.241531],[20.1592684,46.2415751],[20.1583504,46.2418505],[20.1549473,46.2422869],[20.1510796,46.2351538],[20.1493804,46.232459],[20.1459914,46.2281144]]],"terms_url":"http://www.geo.u-szeged.hu/","terms_text":"SZTE TFGT - University of Szeged"},{"id":"tnris.org","name":"Texas Orthophoto","type":"tms","template":"https://txgi.tnris.org/login/path/ecology-fiona-poem-romeo/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=texas&STYLE=&FORMAT=image/png&tileMatrixSet=0to20&tileMatrix=0to20:{zoom}&tileRow={y}&tileCol={x}","scaleExtent":[0,20],"polygon":[[[-99.9985439,34.5601834],[-95.55654502453,33.99257450647],[-93.89679027134,33.61039304449],[-93.98468089634,32.04103124103],[-93.41613841587,31.02505269211],[-93.74531484297,29.57268254375],[-96.50492070332,28.23158511753],[-97.36942054453,26.95467452634],[-97.04866958924,25.80530249434],[-99.0734177889,26.32559221139],[-100.76599193149,29.02531904433],[-102.3315436893,29.8433892263],[-103.13354564242,28.88112103669],[-104.2887874222,29.28831477845],[-104.7269783935,29.94815782859],[-104.72696778796,30.23535241761],[-106.53450082091,31.78456647831],[-106.75767043939,31.78457253947],[-106.75766067978,32.04385536686],[-106.61848436611,32.04385159755],[-103.11949492759,32.04375683439],[-103.09544343487,36.50045758762],[-103.05798056071,36.54268645422],[-100.00042146824,36.54222227302],[-99.9985439,34.5601834]]],"terms_url":"https://tnris.org/maps-and-data/online-mapping-services/"},{"id":"tf-landscape","name":"Thunderforest Landscape","type":"tms","template":"https://{switch:a,b,c}.tile.thunderforest.com/landscape/{zoom}/{x}/{y}.png","scaleExtent":[0,22],"terms_url":"http://www.thunderforest.com/terms/","terms_text":"Maps © Thunderforest, Data © OpenStreetMap contributors"},{"id":"Toulouse-Orthophotoplan-2007","name":"Toulouse - Orthophotoplan 2007","type":"tms","template":"http://wms.openstreetmap.fr/tms/1.0.0/toulouse_ortho2007/{zoom}/{x}/{y}","scaleExtent":[0,22],"polygon":[[[1.1919978,43.6328791],[1.2015377,43.6329729],[1.2011107,43.6554932],[1.2227985,43.6557029],[1.2226231,43.6653353],[1.2275341,43.6653849],[1.2275417,43.6656387],[1.2337568,43.6656883],[1.2337644,43.6650153],[1.2351218,43.6650319],[1.2350913,43.6670729],[1.2443566,43.6671556],[1.2441584,43.6743925],[1.2493973,43.6744256],[1.2493973,43.6746628],[1.2555666,43.6747234],[1.2555742,43.6744532],[1.2569545,43.6744697],[1.2568782,43.678529],[1.2874873,43.6788257],[1.2870803,43.7013229],[1.3088219,43.7014632],[1.3086493,43.7127673],[1.3303262,43.7129544],[1.3300242,43.7305221],[1.3367106,43.7305845],[1.3367322,43.7312235],[1.3734338,43.7310456],[1.3735848,43.7245772],[1.4604504,43.7252947],[1.4607783,43.7028034],[1.4824875,43.7029516],[1.4829828,43.6692071],[1.5046832,43.6693616],[1.5048383,43.6581174],[1.5265475,43.6582656],[1.5266945,43.6470298],[1.548368,43.6471633],[1.5485357,43.6359385],[1.5702172,43.636082],[1.5705123,43.6135777],[1.5488166,43.6134276],[1.549097,43.5909479],[1.5707695,43.5910694],[1.5709373,43.5798341],[1.5793714,43.5798894],[1.5794782,43.5737682],[1.5809119,43.5737792],[1.5810859,43.5573794],[1.5712334,43.5573131],[1.5716504,43.5235497],[1.3984804,43.5222618],[1.3986509,43.5110113],[1.3120959,43.5102543],[1.3118968,43.5215192],[1.2902569,43.5213126],[1.2898637,43.5438168],[1.311517,43.5440133],[1.3113271,43.5552596],[1.3036924,43.5551924],[1.3036117,43.5595099],[1.2955449,43.5594317],[1.2955449,43.5595489],[1.2895595,43.5594473],[1.2892899,43.5775366],[1.2675698,43.5773647],[1.2673973,43.5886141],[1.25355,43.5885047],[1.2533774,43.5956282],[1.2518029,43.5956282],[1.2518029,43.5949409],[1.2350437,43.5947847],[1.2350437,43.5945972],[1.2239572,43.5945972],[1.2239357,43.5994708],[1.2139708,43.599299],[1.2138845,43.6046408],[1.2020647,43.6044846],[1.2019464,43.61048],[1.1924294,43.6103695],[1.1919978,43.6328791]]],"terms_url":"https://wiki.openstreetmap.org/wiki/Toulouse/ToulouseMetropoleData","terms_text":"ToulouseMetropole"},{"id":"Toulouse-Orthophotoplan-2011","name":"Toulouse - Orthophotoplan 2011","type":"tms","template":"http://wms.openstreetmap.fr/tms/1.0.0/toulouse_ortho2011/{zoom}/{x}/{y}","scaleExtent":[0,22],"polygon":[[[1.1135067,43.6867566],[1.1351836,43.6870842],[1.1348907,43.6983471],[1.1782867,43.6990338],[1.1779903,43.7102786],[1.1996591,43.7106144],[1.1993387,43.7218722],[1.2427356,43.7225269],[1.2424336,43.7337491],[1.2641536,43.734092],[1.2638301,43.7453588],[1.2855285,43.7456548],[1.2852481,43.756935],[1.306925,43.757231],[1.3066446,43.7684779],[1.3283431,43.7687894],[1.3280842,43.780034],[1.4367275,43.7815757],[1.4373098,43.7591004],[1.4590083,43.7593653],[1.4593318,43.7481479],[1.4810303,43.7483972],[1.4813322,43.7371777],[1.5030307,43.7374115],[1.5035915,43.7149664],[1.5253115,43.7151846],[1.5256135,43.7040057],[1.5472688,43.7042552],[1.5475708,43.6930431],[1.5692045,43.6932926],[1.5695712,43.6820316],[1.5912049,43.6822656],[1.5917441,43.6597998],[1.613421,43.6600339],[1.613723,43.6488291],[1.6353783,43.6490788],[1.6384146,43.5140731],[1.2921649,43.5094658],[1.2918629,43.5206966],[1.2702076,43.5203994],[1.2698841,43.5316437],[1.2482288,43.531331],[1.2476048,43.5537788],[1.2259628,43.5534914],[1.2256819,43.564716],[1.2039835,43.564419],[1.2033148,43.5869049],[1.1816164,43.5865611],[1.1810237,43.6090368],[1.1592821,43.6086932],[1.1589585,43.6199523],[1.1372601,43.6196244],[1.1365933,43.642094],[1.1149055,43.6417629],[1.1135067,43.6867566]]],"terms_url":"https://wiki.openstreetmap.org/wiki/Toulouse/ToulouseMetropoleData","terms_text":"ToulouseMetropole"},{"id":"Toulouse-Orthophotoplan-2013","name":"Toulouse - Orthophotoplan 2013","type":"tms","template":"http://wms.openstreetmap.fr/tms/1.0.0/toulouse_2013/{zoom}/{x}/{y}","scaleExtent":[0,22],"polygon":[[[1.1135067,43.6867566],[1.1351836,43.6870842],[1.1348907,43.6983471],[1.1782867,43.6990338],[1.1779903,43.7102786],[1.1996591,43.7106144],[1.1993387,43.7218722],[1.2427356,43.7225269],[1.2424336,43.7337491],[1.2641536,43.734092],[1.2638301,43.7453588],[1.2855285,43.7456548],[1.2852481,43.756935],[1.306925,43.757231],[1.3066446,43.7684779],[1.3283431,43.7687894],[1.3280842,43.780034],[1.4367275,43.7815757],[1.4373098,43.7591004],[1.4590083,43.7593653],[1.4593318,43.7481479],[1.4810303,43.7483972],[1.4813322,43.7371777],[1.5030307,43.7374115],[1.5035915,43.7149664],[1.5253115,43.7151846],[1.5256135,43.7040057],[1.5472688,43.7042552],[1.5475708,43.6930431],[1.5692045,43.6932926],[1.5695712,43.6820316],[1.5912049,43.6822656],[1.5917441,43.6597998],[1.613421,43.6600339],[1.613723,43.6488291],[1.6353783,43.6490788],[1.6384146,43.5140731],[1.2921649,43.5094658],[1.2918629,43.5206966],[1.2702076,43.5203994],[1.2698841,43.5316437],[1.2482288,43.531331],[1.2476048,43.5537788],[1.2259628,43.5534914],[1.2256819,43.564716],[1.2039835,43.564419],[1.2033148,43.5869049],[1.1816164,43.5865611],[1.1810237,43.6090368],[1.1592821,43.6086932],[1.1589585,43.6199523],[1.1372601,43.6196244],[1.1365933,43.642094],[1.1149055,43.6417629],[1.1135067,43.6867566]]],"terms_url":"https://wiki.openstreetmap.org/wiki/Toulouse/ToulouseMetropoleData","terms_text":"ToulouseMetropole"},{"id":"Toulouse-Orthophotoplan-2015","name":"Toulouse - Orthophotoplan 2015","type":"tms","template":"http://wms.openstreetmap.fr/tms/1.0.0/toulouse_2015/{zoom}/{x}/{y}","scaleExtent":[0,22],"polygon":[[[1.1135067,43.6867566],[1.1351836,43.6870842],[1.1348907,43.6983471],[1.1782867,43.6990338],[1.1779903,43.7102786],[1.1996591,43.7106144],[1.1993387,43.7218722],[1.2427356,43.7225269],[1.2424336,43.7337491],[1.2641536,43.734092],[1.2638301,43.7453588],[1.2855285,43.7456548],[1.2852481,43.756935],[1.306925,43.757231],[1.3066446,43.7684779],[1.3283431,43.7687894],[1.3280842,43.780034],[1.4367275,43.7815757],[1.4373098,43.7591004],[1.4590083,43.7593653],[1.4593318,43.7481479],[1.4810303,43.7483972],[1.4813322,43.7371777],[1.5030307,43.7374115],[1.5035915,43.7149664],[1.5253115,43.7151846],[1.5256135,43.7040057],[1.5472688,43.7042552],[1.5475708,43.6930431],[1.5692045,43.6932926],[1.5695712,43.6820316],[1.5912049,43.6822656],[1.5917441,43.6597998],[1.613421,43.6600339],[1.613723,43.6488291],[1.6353783,43.6490788],[1.6384146,43.5140731],[1.2921649,43.5094658],[1.2918629,43.5206966],[1.2702076,43.5203994],[1.2698841,43.5316437],[1.2482288,43.531331],[1.2476048,43.5537788],[1.2259628,43.5534914],[1.2256819,43.564716],[1.2039835,43.564419],[1.2033148,43.5869049],[1.1816164,43.5865611],[1.1810237,43.6090368],[1.1592821,43.6086932],[1.1589585,43.6199523],[1.1372601,43.6196244],[1.1365933,43.642094],[1.1149055,43.6417629],[1.1135067,43.6867566]]],"terms_url":"https://wiki.openstreetmap.org/wiki/Toulouse/ToulouseMetropoleData","terms_text":"ToulouseMetropole"},{"id":"Tours-Orthophoto-2008_2010","name":"Tours - Orthophotos 2008-2010","type":"tms","template":"http://wms.openstreetmap.fr/tms/1.0.0/tours/{zoom}/{x}/{y}","scaleExtent":[0,20],"polygon":[[[0.5457462,47.465264],[0.54585,47.4608163],[0.5392188,47.4606983],[0.5393484,47.456243],[0.5327959,47.4561003],[0.5329011,47.451565],[0.52619,47.4514013],[0.5265854,47.4424884],[0.5000941,47.4420739],[0.5002357,47.4375835],[0.4936014,47.4374324],[0.4937,47.4329285],[0.4606141,47.4324593],[0.4607248,47.4279827],[0.4541016,47.4278125],[0.454932,47.4053921],[0.4615431,47.4054476],[0.4619097,47.3964924],[0.4684346,47.3966005],[0.4691319,47.3786415],[0.4757125,47.3787609],[0.4762116,47.3652018],[0.4828297,47.3653499],[0.4829611,47.3608321],[0.4763543,47.360743],[0.476654,47.3517263],[0.4700497,47.3516186],[0.4701971,47.3471313],[0.4637503,47.3470104],[0.4571425,47.3424146],[0.4572922,47.3379061],[0.4506741,47.3378081],[0.4508379,47.3333051],[0.4442212,47.3332032],[0.4443809,47.328711],[0.4311392,47.3284977],[0.4316262,47.3150004],[0.4382432,47.3151136],[0.4383815,47.3106174],[0.4714487,47.3111374],[0.4713096,47.3156565],[0.477888,47.3157542],[0.4780733,47.3112802],[0.4846826,47.3113639],[0.4848576,47.3068686],[0.4914359,47.3069803],[0.491745,47.2979733],[0.4851578,47.2978722],[0.4854269,47.2888744],[0.4788485,47.2887697],[0.4791574,47.2797818],[0.4857769,47.2799005],[0.4859107,47.2753885],[0.492539,47.2755029],[0.4926669,47.2710127],[0.4992986,47.2711066],[0.4994296,47.2666116],[0.5192658,47.2669245],[0.5194225,47.2624231],[0.5260186,47.2625205],[0.5258735,47.2670183],[0.5456972,47.2673383],[0.5455537,47.2718283],[0.5587737,47.2720366],[0.5586259,47.2765185],[0.5652252,47.2766278],[0.5650848,47.2811206],[0.5716753,47.2812285],[0.5715223,47.2857217],[0.5781436,47.2858299],[0.5779914,47.2903294],[0.5846023,47.2904263],[0.5843076,47.2994231],[0.597499,47.2996094],[0.5976637,47.2951375],[0.6571596,47.2960036],[0.6572988,47.2915091],[0.6705019,47.2917186],[0.6703475,47.2962082],[0.6836175,47.2963688],[0.6834322,47.3008929],[0.690062,47.3009558],[0.6899241,47.3054703],[0.7362019,47.3061157],[0.7360848,47.3106063],[0.7559022,47.3108935],[0.7557718,47.315392],[0.7623755,47.3154716],[0.7622314,47.3199941],[0.7754911,47.3201546],[0.77497,47.3388218],[0.7745786,47.351628],[0.7680363,47.3515901],[0.767589,47.3605298],[0.7742443,47.3606238],[0.7733465,47.3921266],[0.7667434,47.3920195],[0.7664411,47.4010837],[0.7730647,47.4011115],[0.7728868,47.4101297],[0.7661849,47.4100226],[0.7660267,47.4145044],[0.7527613,47.4143038],[0.7529788,47.4098086],[0.7462373,47.4097016],[0.7459424,47.4232208],[0.7392324,47.4231451],[0.738869,47.4366116],[0.7323267,47.4365171],[0.7321869,47.4410556],[0.7255048,47.44098],[0.7254209,47.4453479],[0.7318793,47.4454803],[0.7318514,47.4501126],[0.7384496,47.450226],[0.7383098,47.454631],[0.7449359,47.4547444],[0.7443209,47.4771985],[0.7310685,47.4769717],[0.7309008,47.4815445],[0.7176205,47.4812611],[0.7177883,47.4768394],[0.69777,47.4764993],[0.6980496,47.4719827],[0.6914514,47.4718882],[0.6917309,47.4630241],[0.6851048,47.4629295],[0.684937,47.4673524],[0.678255,47.4673335],[0.6779754,47.4762158],[0.6714051,47.4761592],[0.6710417,47.4881952],[0.6577334,47.4879685],[0.6578173,47.48504],[0.6511911,47.4848322],[0.6514707,47.4758568],[0.6448166,47.4757245],[0.6449284,47.4712646],[0.6117976,47.4707543],[0.6118815,47.4663129],[0.6052833,47.4661239],[0.6054231,47.4616631],[0.5988808,47.4615497],[0.5990206,47.4570886],[0.572488,47.4566916],[0.5721805,47.4656513],[0.5457462,47.465264]]],"terms_url":"http://wiki.openstreetmap.org/wiki/Tours/Orthophoto","terms_text":"Orthophoto Tour(s) Plus 2008"},{"id":"Tours-Orthophoto-2013","name":"Tours - Orthophotos 2013","type":"tms","template":"http://wms.openstreetmap.fr/tms/1.0.0/tours_2013/{zoom}/{x}/{y}","scaleExtent":[0,22],"polygon":[[[0.427093505859375,47.26199018174824],[0.427093505859375,47.50096732311069],[0.814361572265625,47.50096732311069],[0.814361572265625,47.26199018174824],[0.427093505859375,47.26199018174824]]],"terms_url":"http://wiki.openstreetmap.org/wiki/Tours/Orthophoto","terms_text":"Orthophoto Tour(s)plus 2013"},{"id":"US_Forest_Service_roads","name":"U.S. Forest Service roads","type":"tms","template":"http://osm.cycle.travel/forest/{zoom}/{x}/{y}.png","scaleExtent":[0,19],"polygon":[[[-124.7617886,48.4130148],[-124.6059492,45.90245],[-124.9934269,40.0557614],[-122.5369737,36.8566086],[-119.9775867,33.0064099],[-117.675935,32.4630223],[-114.8612307,32.4799891],[-111.0089311,31.336015],[-108.1992687,31.3260016],[-108.1871123,31.7755116],[-106.5307225,31.7820947],[-106.4842052,31.7464455],[-106.429317,31.7520583],[-106.2868855,31.5613291],[-106.205248,31.446704],[-105.0205259,30.5360988],[-104.5881916,29.6997856],[-103.2518856,28.8908685],[-102.7173632,29.3920567],[-102.1513983,29.7475702],[-101.2552871,29.4810523],[-100.0062436,28.0082173],[-99.2351068,26.4475962],[-98.0109067,25.9928035],[-97.435024,25.8266009],[-96.9555259,25.9821589],[-96.8061741,27.7978168],[-95.5563349,28.5876066],[-93.7405308,29.4742093],[-90.9028456,28.8564513],[-88.0156706,28.9944338],[-88.0162494,30.0038862],[-86.0277506,30.0047454],[-84.0187909,28.9961781],[-81.9971976,25.9826768],[-81.9966618,25.0134917],[-84.0165592,25.0125783],[-84.0160068,24.0052745],[-80.0199985,24.007096],[-79.8901116,26.8550713],[-80.0245309,32.0161282],[-75.4147385,35.0531894],[-74.0211163,39.5727927],[-72.002019,40.9912464],[-69.8797398,40.9920457],[-69.8489304,43.2619916],[-66.9452845,44.7104937],[-67.7596632,47.0990024],[-69.2505131,47.5122328],[-70.4614886,46.2176574],[-71.412273,45.254878],[-72.0222508,45.0059846],[-75.0798841,44.9802854],[-76.9023061,43.8024568],[-78.7623935,43.6249578],[-79.15798,43.4462589],[-79.0060087,42.8005317],[-82.662475,41.6889458],[-82.1761642,43.588535],[-83.2813977,46.138853],[-87.5064535,48.0142702],[-88.3492194,48.2963271],[-89.4353148,47.9837822],[-93.9981078,49.0067142],[-95.1105379,49.412004],[-96.0131199,49.0060547],[-123.3228926,49.0042878],[-123.2275233,48.1849927],[-124.7617886,48.4130148]],[[-160.5787616,22.5062947],[-160.5782192,21.4984647],[-158.7470604,21.2439843],[-157.5083185,20.995803],[-155.9961942,18.7790194],[-154.6217803,18.7586966],[-154.6890176,19.8805722],[-156.2927622,21.2225888],[-157.5047384,21.9984962],[-159.0093692,22.5070181],[-160.5787616,22.5062947]],[[-167.1571546,68.721974],[-164.8553982,67.0255078],[-168.002195,66.0017503],[-169.0087448,66.001546],[-169.0075381,64.9987675],[-172.5143281,63.8767267],[-173.8197023,59.74014],[-162.5018149,58.0005815],[-160.0159024,58.0012389],[-160.0149725,57.000035],[-160.5054788,56.9999017],[-165.8092575,54.824847],[-178.000097,52.2446469],[-177.9992996,51.2554252],[-171.4689067,51.8215329],[-162.40251,53.956664],[-159.0075717,55.002502],[-158.0190709,55.0027849],[-151.9963213,55.9991902],[-151.500341,57.9987853],[-151.5012894,58.9919816],[-138.5159989,58.9953194],[-138.5150471,57.9986434],[-133.9948193,54.0031685],[-130.0044418,54.0043387],[-130.0070826,57.0000507],[-131.975877,56.9995156],[-135.1229873,59.756601],[-138.0071813,59.991805],[-139.1715881,60.4127229],[-140.9874011,61.0118551],[-140.9683975,69.9535069],[-156.176891,71.5633329],[-160.413634,70.7397728],[-163.0218273,69.9707435],[-164.9717003,68.994689],[-167.1571546,68.721974]]]},{"id":"Zuerich-zh_uebersichtsplan-tms","name":"Übersichtsplan Zürich","type":"tms","template":"http://mapproxy.sosm.ch:8080/tiles/zh_uebersichtsplan/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","scaleExtent":[0,21],"polygon":[[[8.4482,47.321],[8.4482,47.4339],[8.6248,47.4339],[8.6248,47.321],[8.4482,47.321]]],"terms_text":"Stadt Zürich Open Government Data"},{"id":"USGS-Large_Scale","name":"USGS Large Scale Imagery","type":"tms","template":"http://{switch:a,b,c}.tile.openstreetmap.us/usgs_large_scale/{zoom}/{x}/{y}.jpg","scaleExtent":[12,20],"polygon":[[[-123.2549305,48.7529029],[-123.2549305,48.5592263],[-123.192224,48.5592263],[-123.192224,48.4348366],[-122.9419646,48.4348366],[-122.9419646,48.3720812],[-122.8806229,48.3720812],[-122.8806229,48.3094763],[-122.8167566,48.3094763],[-122.8167566,48.1904587],[-123.0041133,48.1904587],[-123.0041133,48.1275918],[-123.058416,48.1275918],[-123.058416,48.190514],[-123.254113,48.190514],[-123.254113,48.1274982],[-123.3706593,48.1274982],[-123.3706593,48.1908403],[-124.0582632,48.1908403],[-124.0582632,48.253442],[-124.1815163,48.253442],[-124.1815163,48.3164666],[-124.4319117,48.3164666],[-124.4319117,48.3782613],[-124.5564618,48.3782613],[-124.5564618,48.4408305],[-124.7555107,48.4408305],[-124.7555107,48.1914986],[-124.8185282,48.1914986],[-124.8185282,48.1228381],[-124.7552951,48.1228381],[-124.7552951,47.5535253],[-124.3812108,47.5535253],[-124.3812108,47.1218696],[-124.1928897,47.1218696],[-124.1928897,43.7569431],[-124.4443382,43.7569431],[-124.4443382,43.1425556],[-124.6398855,43.1425556],[-124.6398855,42.6194503],[-124.4438525,42.6194503],[-124.4438525,39.8080662],[-123.8815685,39.8080662],[-123.8815685,39.1102825],[-123.75805,39.1102825],[-123.75805,38.4968799],[-123.2702803,38.4968799],[-123.2702803,37.9331905],[-122.8148084,37.9331905],[-122.8148084,37.8019606],[-122.5664316,37.8019606],[-122.5664316,36.9319611],[-121.8784026,36.9319611],[-121.8784026,36.6897596],[-122.0034748,36.6897596],[-122.0034748,36.4341056],[-121.9414159,36.4341056],[-121.9414159,35.9297636],[-121.5040977,35.9297636],[-121.5040977,35.8100273],[-121.3790276,35.8100273],[-121.3790276,35.4239164],[-120.9426515,35.4239164],[-120.9426515,35.1849683],[-120.8171978,35.1849683],[-120.8171978,35.1219894],[-120.6918447,35.1219894],[-120.6918447,34.4966794],[-120.5045898,34.4966794],[-120.5045898,34.4339651],[-120.0078775,34.4339651],[-120.0078775,34.3682626],[-119.5283517,34.3682626],[-119.5283517,34.0576434],[-119.0060985,34.0576434],[-119.0060985,33.9975267],[-118.5046259,33.9975267],[-118.5046259,33.8694631],[-118.4413209,33.8694631],[-118.4413209,33.6865253],[-118.066912,33.6865253],[-118.066912,33.3063832],[-117.5030045,33.3063832],[-117.5030045,33.0500337],[-117.3188195,33.0500337],[-117.3188195,32.6205888],[-117.1917023,32.6205888],[-117.1917023,32.4974566],[-116.746496,32.4974566],[-116.746496,32.5609161],[-115.9970138,32.5609161],[-115.9970138,32.6264942],[-114.8808125,32.6264942],[-114.8808125,32.4340796],[-114.6294474,32.4340796],[-114.6294474,32.3731636],[-114.4447437,32.3731636],[-114.4447437,32.3075418],[-114.2557628,32.3075418],[-114.2557628,32.2444561],[-114.0680274,32.2444561],[-114.0680274,32.1829113],[-113.8166499,32.1829113],[-113.8166499,32.1207622],[-113.6307421,32.1207622],[-113.6307421,32.0565099],[-113.4417495,32.0565099],[-113.4417495,31.9984372],[-113.2546027,31.9984372],[-113.2546027,31.9325434],[-113.068072,31.9325434],[-113.068072,31.8718062],[-112.8161105,31.8718062],[-112.8161105,31.8104171],[-112.6308756,31.8104171],[-112.6308756,31.7464723],[-112.4418918,31.7464723],[-112.4418918,31.6856001],[-112.257192,31.6856001],[-112.257192,31.6210352],[-112.0033787,31.6210352],[-112.0033787,31.559584],[-111.815619,31.559584],[-111.815619,31.4970238],[-111.6278586,31.4970238],[-111.6278586,31.4339867],[-111.4418978,31.4339867],[-111.4418978,31.3733859],[-111.2559708,31.3733859],[-111.2559708,31.3113225],[-108.1845822,31.3113225],[-108.1845822,31.7459502],[-106.5065055,31.7459502],[-106.5065055,31.6842308],[-106.3797265,31.6842308],[-106.3797265,31.621752],[-106.317434,31.621752],[-106.317434,31.4968167],[-106.2551769,31.4968167],[-106.2551769,31.4344889],[-106.1924698,31.4344889],[-106.1924698,31.3721296],[-106.0039212,31.3721296],[-106.0039212,31.309328],[-105.9416582,31.309328],[-105.9416582,31.2457547],[-105.8798174,31.2457547],[-105.8798174,31.1836194],[-105.8162349,31.1836194],[-105.8162349,31.1207155],[-105.6921198,31.1207155],[-105.6921198,31.0584835],[-105.6302881,31.0584835],[-105.6302881,30.9328271],[-105.5044418,30.9328271],[-105.5044418,30.8715864],[-105.4412973,30.8715864],[-105.4412973,30.808463],[-105.3781497,30.808463],[-105.3781497,30.7471828],[-105.1904658,30.7471828],[-105.1904658,30.6843231],[-105.1286244,30.6843231],[-105.1286244,30.6199737],[-105.0036504,30.6199737],[-105.0036504,30.5589058],[-104.9417962,30.5589058],[-104.9417962,30.4963236],[-104.8782018,30.4963236],[-104.8782018,30.3098261],[-104.8155257,30.3098261],[-104.8155257,30.2478305],[-104.7536079,30.2478305],[-104.7536079,29.9353916],[-104.690949,29.9353916],[-104.690949,29.8090156],[-104.6291301,29.8090156],[-104.6291301,29.6843577],[-104.5659869,29.6843577],[-104.5659869,29.6223459],[-104.5037188,29.6223459],[-104.5037188,29.5595436],[-104.4410072,29.5595436],[-104.4410072,29.4974832],[-104.2537551,29.4974832],[-104.2537551,29.3716718],[-104.1291984,29.3716718],[-104.1291984,29.3091621],[-104.0688737,29.3091621],[-104.0688737,29.2467276],[-103.8187309,29.2467276],[-103.8187309,29.1843076],[-103.755736,29.1843076],[-103.755736,29.1223174],[-103.5667542,29.1223174],[-103.5667542,29.0598119],[-103.5049819,29.0598119],[-103.5049819,28.9967506],[-103.3165753,28.9967506],[-103.3165753,28.9346923],[-103.0597572,28.9346923],[-103.0597572,29.0592965],[-102.9979694,29.0592965],[-102.9979694,29.1212855],[-102.9331397,29.1212855],[-102.9331397,29.1848575],[-102.8095989,29.1848575],[-102.8095989,29.2526154],[-102.8701345,29.2526154],[-102.8701345,29.308096],[-102.8096681,29.308096],[-102.8096681,29.3715484],[-102.7475655,29.3715484],[-102.7475655,29.5581899],[-102.684554,29.5581899],[-102.684554,29.6847655],[-102.4967764,29.6847655],[-102.4967764,29.7457694],[-102.3086647,29.7457694],[-102.3086647,29.8086627],[-102.1909323,29.8086627],[-102.1909323,29.7460097],[-101.5049914,29.7460097],[-101.5049914,29.6846777],[-101.3805796,29.6846777],[-101.3805796,29.5594459],[-101.3175057,29.5594459],[-101.3175057,29.4958934],[-101.1910075,29.4958934],[-101.1910075,29.4326115],[-101.067501,29.4326115],[-101.067501,29.308808],[-100.9418897,29.308808],[-100.9418897,29.2456231],[-100.8167271,29.2456231],[-100.8167271,29.1190449],[-100.7522672,29.1190449],[-100.7522672,29.0578214],[-100.6925358,29.0578214],[-100.6925358,28.8720431],[-100.6290158,28.8720431],[-100.6290158,28.8095363],[-100.5679901,28.8095363],[-100.5679901,28.622554],[-100.5040411,28.622554],[-100.5040411,28.5583804],[-100.4421832,28.5583804],[-100.4421832,28.4968266],[-100.379434,28.4968266],[-100.379434,28.3092865],[-100.3171942,28.3092865],[-100.3171942,28.1835681],[-100.254483,28.1835681],[-100.254483,28.1213885],[-100.1282282,28.1213885],[-100.1282282,28.059215],[-100.0659537,28.059215],[-100.0659537,27.9966087],[-100.0023855,27.9966087],[-100.0023855,27.9332152],[-99.9426497,27.9332152],[-99.9426497,27.7454658],[-99.816851,27.7454658],[-99.816851,27.6834301],[-99.7541346,27.6834301],[-99.7541346,27.6221543],[-99.6291629,27.6221543],[-99.6291629,27.5588977],[-99.5672838,27.5588977],[-99.5672838,27.4353752],[-99.5041798,27.4353752],[-99.5041798,27.3774021],[-99.5671796,27.3774021],[-99.5671796,27.2463726],[-99.504975,27.2463726],[-99.504975,26.9965649],[-99.4427427,26.9965649],[-99.4427427,26.872803],[-99.3800633,26.872803],[-99.3800633,26.8068179],[-99.3190684,26.8068179],[-99.3190684,26.7473614],[-99.2537541,26.7473614],[-99.2537541,26.6210068],[-99.1910617,26.6210068],[-99.1910617,26.4956737],[-99.1300639,26.4956737],[-99.1300639,26.3713808],[-99.0029473,26.3713808],[-99.0029473,26.3093836],[-98.816572,26.3093836],[-98.816572,26.2457762],[-98.6920082,26.2457762],[-98.6920082,26.1837096],[-98.4440896,26.1837096],[-98.4440896,26.1217217],[-98.3823181,26.1217217],[-98.3823181,26.0596488],[-98.2532707,26.0596488],[-98.2532707,25.9986871],[-98.0109084,25.9986871],[-98.0109084,25.9932255],[-97.6932319,25.9932255],[-97.6932319,25.9334103],[-97.6313904,25.9334103],[-97.6313904,25.8695893],[-97.5046779,25.8695893],[-97.5046779,25.8073488],[-97.3083401,25.8073488],[-97.3083401,25.8731159],[-97.2456326,25.8731159],[-97.2456326,25.9353731],[-97.1138939,25.9353731],[-97.1138939,27.6809179],[-97.0571035,27.6809179],[-97.0571035,27.8108242],[-95.5810766,27.8108242],[-95.5810766,28.7468827],[-94.271041,28.7468827],[-94.271041,29.5594076],[-92.5029947,29.5594076],[-92.5029947,29.4974754],[-91.8776216,29.4974754],[-91.8776216,29.3727013],[-91.378418,29.3727013],[-91.378418,29.2468326],[-91.3153953,29.2468326],[-91.3153953,29.1844301],[-91.1294702,29.1844301],[-91.1294702,29.1232559],[-91.0052632,29.1232559],[-91.0052632,28.9968437],[-89.4500159,28.9968437],[-89.4500159,28.8677422],[-88.8104309,28.8677422],[-88.8104309,30.1841864],[-85.8791527,30.1841864],[-85.8791527,29.5455038],[-84.8368083,29.5455038],[-84.8368083,29.6225158],[-84.7482786,29.6225158],[-84.7482786,29.683624],[-84.685894,29.683624],[-84.685894,29.7468386],[-83.6296975,29.7468386],[-83.6296975,29.4324361],[-83.3174937,29.4324361],[-83.3174937,29.0579442],[-82.879659,29.0579442],[-82.879659,27.7453529],[-82.8182822,27.7453529],[-82.8182822,26.9290868],[-82.3796782,26.9290868],[-82.3796782,26.3694183],[-81.8777106,26.3694183],[-81.8777106,25.805971],[-81.5036862,25.805971],[-81.5036862,25.7474753],[-81.4405462,25.7474753],[-81.4405462,25.6851489],[-81.3155883,25.6851489],[-81.3155883,25.5600985],[-81.2538534,25.5600985],[-81.2538534,25.4342361],[-81.1902012,25.4342361],[-81.1902012,25.1234341],[-81.1288133,25.1234341],[-81.1288133,25.0619389],[-81.0649231,25.0619389],[-81.0649231,24.8157807],[-81.6289469,24.8157807],[-81.6289469,24.7538367],[-81.6907173,24.7538367],[-81.6907173,24.6899374],[-81.8173189,24.6899374],[-81.8173189,24.6279161],[-82.1910041,24.6279161],[-82.1910041,24.496294],[-81.6216596,24.496294],[-81.6216596,24.559484],[-81.372006,24.559484],[-81.372006,24.6220687],[-81.0593278,24.6220687],[-81.0593278,24.684826],[-80.9347147,24.684826],[-80.9347147,24.7474828],[-80.7471081,24.7474828],[-80.7471081,24.8100618],[-80.3629898,24.8100618],[-80.3629898,25.1175858],[-80.122344,25.1175858],[-80.122344,25.7472357],[-80.0588458,25.7472357],[-80.0588458,26.3708251],[-79.995837,26.3708251],[-79.995837,26.9398003],[-80.0587265,26.9398003],[-80.0587265,27.1277466],[-80.1226251,27.1277466],[-80.1226251,27.2534279],[-80.1846956,27.2534279],[-80.1846956,27.3781229],[-80.246175,27.3781229],[-80.246175,27.5658729],[-80.3094768,27.5658729],[-80.3094768,27.7530311],[-80.3721485,27.7530311],[-80.3721485,27.8774451],[-80.4351457,27.8774451],[-80.4351457,28.0033366],[-80.4966078,28.0033366],[-80.4966078,28.1277326],[-80.5587159,28.1277326],[-80.5587159,28.3723509],[-80.4966335,28.3723509],[-80.4966335,29.5160326],[-81.1213644,29.5160326],[-81.1213644,31.6846966],[-80.6018723,31.6846966],[-80.6018723,32.2475309],[-79.4921024,32.2475309],[-79.4921024,32.9970261],[-79.1116488,32.9970261],[-79.1116488,33.3729457],[-78.6153621,33.3729457],[-78.6153621,33.8097638],[-77.9316963,33.8097638],[-77.9316963,33.8718243],[-77.8692252,33.8718243],[-77.8692252,34.0552454],[-77.6826392,34.0552454],[-77.6826392,34.2974598],[-77.2453509,34.2974598],[-77.2453509,34.5598585],[-76.4973277,34.5598585],[-76.4973277,34.622796],[-76.4337602,34.622796],[-76.4337602,34.6849285],[-76.373212,34.6849285],[-76.373212,34.7467674],[-76.3059364,34.7467674],[-76.3059364,34.808551],[-76.2468017,34.808551],[-76.2468017,34.8728418],[-76.1825922,34.8728418],[-76.1825922,34.9335332],[-76.120814,34.9335332],[-76.120814,34.9952359],[-75.9979015,34.9952359],[-75.9979015,35.0578182],[-75.870338,35.0578182],[-75.870338,35.1219097],[-75.7462194,35.1219097],[-75.7462194,35.1818911],[-75.4929694,35.1818911],[-75.4929694,35.3082988],[-75.4325662,35.3082988],[-75.4325662,35.7542495],[-75.4969907,35.7542495],[-75.4969907,37.8105602],[-75.3082972,37.8105602],[-75.3082972,37.8720088],[-75.245601,37.8720088],[-75.245601,37.9954849],[-75.1828751,37.9954849],[-75.1828751,38.0585079],[-75.1184793,38.0585079],[-75.1184793,38.2469091],[-75.0592098,38.2469091],[-75.0592098,38.3704316],[-74.9948111,38.3704316],[-74.9948111,38.8718417],[-74.4878252,38.8718417],[-74.4878252,39.3089428],[-74.1766317,39.3089428],[-74.1766317,39.6224653],[-74.0567045,39.6224653],[-74.0567045,39.933178],[-73.9959035,39.933178],[-73.9959035,40.1854852],[-73.9341593,40.1854852],[-73.9341593,40.4959486],[-73.8723024,40.4959486],[-73.8723024,40.5527135],[-71.8074506,40.5527135],[-71.8074506,41.3088005],[-70.882512,41.3088005],[-70.882512,41.184978],[-70.7461947,41.184978],[-70.7461947,41.3091865],[-70.4337553,41.3091865],[-70.4337553,41.4963885],[-69.9334281,41.4963885],[-69.9334281,41.6230802],[-69.869857,41.6230802],[-69.869857,41.8776895],[-69.935791,41.8776895],[-69.935791,42.0032342],[-69.9975823,42.0032342],[-69.9975823,42.0650191],[-70.0606103,42.0650191],[-70.0606103,42.1294348],[-70.5572884,42.1294348],[-70.5572884,43.2487079],[-70.4974097,43.2487079],[-70.4974097,43.3092194],[-70.3704249,43.3092194],[-70.3704249,43.371963],[-70.3085701,43.371963],[-70.3085701,43.4969879],[-70.183921,43.4969879],[-70.183921,43.6223531],[-70.057583,43.6223531],[-70.057583,43.6850173],[-69.7455247,43.6850173],[-69.7455247,43.7476571],[-69.2472845,43.7476571],[-69.2472845,43.8107035],[-69.0560701,43.8107035],[-69.0560701,43.8717247],[-68.9950522,43.8717247],[-68.9950522,43.9982022],[-68.4963672,43.9982022],[-68.4963672,44.0597368],[-68.3081038,44.0597368],[-68.3081038,44.122137],[-68.1851802,44.122137],[-68.1851802,44.3081382],[-67.9956019,44.3081382],[-67.9956019,44.3727489],[-67.8103041,44.3727489],[-67.8103041,44.435178],[-67.4965289,44.435178],[-67.4965289,44.4968776],[-67.37102,44.4968776],[-67.37102,44.5600642],[-67.1848753,44.5600642],[-67.1848753,44.6213345],[-67.1221208,44.6213345],[-67.1221208,44.6867918],[-67.059365,44.6867918],[-67.059365,44.7473657],[-66.9311098,44.7473657],[-66.9311098,44.9406566],[-66.994683,44.9406566],[-66.994683,45.0024514],[-67.0595847,45.0024514],[-67.0595847,45.1273377],[-67.1201974,45.1273377],[-67.1201974,45.1910115],[-67.2469811,45.1910115],[-67.2469811,45.253442],[-67.3177546,45.253442],[-67.3177546,45.1898369],[-67.370749,45.1898369],[-67.370749,45.2534001],[-67.4326888,45.2534001],[-67.4326888,45.3083409],[-67.3708571,45.3083409],[-67.3708571,45.4396986],[-67.4305573,45.4396986],[-67.4305573,45.4950095],[-67.37099,45.4950095],[-67.37099,45.6264543],[-67.6214982,45.6264543],[-67.6214982,45.6896133],[-67.683828,45.6896133],[-67.683828,45.753259],[-67.7462097,45.753259],[-67.7462097,47.1268165],[-67.8700141,47.1268165],[-67.8700141,47.1900278],[-67.9323803,47.1900278],[-67.9323803,47.2539678],[-67.9959387,47.2539678],[-67.9959387,47.3149737],[-68.1206676,47.3149737],[-68.1206676,47.3780823],[-68.4423175,47.3780823],[-68.4423175,47.3166082],[-68.6314305,47.3166082],[-68.6314305,47.2544676],[-68.9978037,47.2544676],[-68.9978037,47.439895],[-69.0607223,47.439895],[-69.0607223,47.5047558],[-69.2538122,47.5047558],[-69.2538122,47.4398084],[-69.3179284,47.4398084],[-69.3179284,47.378601],[-69.4438546,47.378601],[-69.4438546,47.3156274],[-69.5038204,47.3156274],[-69.5038204,47.2525839],[-69.5667838,47.2525839],[-69.5667838,47.1910884],[-69.6303478,47.1910884],[-69.6303478,47.128701],[-69.6933103,47.128701],[-69.6933103,47.0654307],[-69.7557063,47.0654307],[-69.7557063,47.0042751],[-69.8180391,47.0042751],[-69.8180391,46.9415344],[-69.8804023,46.9415344],[-69.8804023,46.8792519],[-69.9421674,46.8792519],[-69.9421674,46.8177399],[-70.0063088,46.8177399],[-70.0063088,46.6920295],[-70.0704265,46.6920295],[-70.0704265,46.4425926],[-70.1945902,46.4425926],[-70.1945902,46.3785887],[-70.2562047,46.3785887],[-70.2562047,46.3152628],[-70.3203651,46.3152628],[-70.3203651,46.0651209],[-70.3814988,46.0651209],[-70.3814988,45.93552],[-70.3201618,45.93552],[-70.3201618,45.879479],[-70.4493131,45.879479],[-70.4493131,45.7538713],[-70.5070021,45.7538713],[-70.5070021,45.6916912],[-70.6316642,45.6916912],[-70.6316642,45.6291619],[-70.7575538,45.6291619],[-70.7575538,45.4414685],[-70.8809878,45.4414685],[-70.8809878,45.3780612],[-71.13328,45.3780612],[-71.13328,45.3151452],[-71.3830282,45.3151452],[-71.3830282,45.253416],[-71.5076448,45.253416],[-71.5076448,45.0655726],[-73.9418929,45.0655726],[-73.9418929,45.0031242],[-74.7469725,45.0031242],[-74.7469725,45.0649003],[-74.8800964,45.0649003],[-74.8800964,45.0029023],[-75.0662455,45.0029023],[-75.0662455,44.9415167],[-75.2539363,44.9415167],[-75.2539363,44.8776043],[-75.3789648,44.8776043],[-75.3789648,44.8153462],[-75.4431283,44.8153462],[-75.4431283,44.7536053],[-75.5666566,44.7536053],[-75.5666566,44.6909879],[-75.6290205,44.6909879],[-75.6290205,44.6284958],[-75.7540484,44.6284958],[-75.7540484,44.566385],[-75.817312,44.566385],[-75.817312,44.5028932],[-75.8799549,44.5028932],[-75.8799549,44.3784946],[-76.1300319,44.3784946],[-76.1300319,44.3159227],[-76.1926961,44.3159227],[-76.1926961,44.2534378],[-76.3182619,44.2534378],[-76.3182619,44.1916726],[-76.3792975,44.1916726],[-76.3792975,44.0653733],[-76.4427584,44.0653733],[-76.4427584,43.9963825],[-76.317027,43.9963825],[-76.317027,43.9414581],[-76.5076611,43.9414581],[-76.5076611,43.8723335],[-76.3829974,43.8723335],[-76.3829974,43.8091872],[-76.2534102,43.8091872],[-76.2534102,43.5665222],[-76.5064833,43.5665222],[-76.5064833,43.5033881],[-76.6331208,43.5033881],[-76.6331208,43.4432252],[-76.6951085,43.4432252],[-76.6951085,43.3786858],[-76.8177798,43.3786858],[-76.8177798,43.318066],[-77.682,43.318066],[-77.682,43.3789376],[-78.0565883,43.3789376],[-78.0565883,43.4396918],[-78.4389748,43.4396918],[-78.4389748,43.3794382],[-78.8803396,43.3794382],[-78.8803396,43.3149724],[-79.1298858,43.3149724],[-79.1298858,43.2429286],[-79.0669615,43.2429286],[-79.0669615,43.1299931],[-79.1298858,43.1299931],[-79.1298858,43.0577305],[-79.071264,43.0577305],[-79.071264,42.9294906],[-78.943264,42.9294906],[-78.943264,42.7542165],[-79.069439,42.7542165],[-79.069439,42.6941622],[-79.133439,42.6941622],[-79.133439,42.6296973],[-79.1947499,42.6296973],[-79.1947499,42.5663538],[-79.3786827,42.5663538],[-79.3786827,42.5033425],[-79.4442961,42.5033425],[-79.4442961,42.4410614],[-79.5679936,42.4410614],[-79.5679936,42.3775264],[-79.6906154,42.3775264],[-79.6906154,42.3171086],[-79.8164642,42.3171086],[-79.8164642,42.2534481],[-80.0052373,42.2534481],[-80.0052373,42.1909188],[-80.1916829,42.1909188],[-80.1916829,42.1272555],[-80.3167992,42.1272555],[-80.3167992,42.0669857],[-80.5063234,42.0669857],[-80.5063234,42.0034331],[-80.6930471,42.0034331],[-80.6930471,41.9415141],[-80.9440403,41.9415141],[-80.9440403,41.8781193],[-81.1942729,41.8781193],[-81.1942729,41.8166455],[-81.3190089,41.8166455],[-81.3190089,41.7545453],[-81.4418435,41.7545453],[-81.4418435,41.690965],[-81.5053523,41.690965],[-81.5053523,41.6301643],[-82.7470081,41.6301643],[-82.7470081,41.7536942],[-82.8839135,41.7536942],[-82.8839135,41.5656075],[-82.9957195,41.5656075],[-82.9957195,41.6270375],[-83.1257796,41.6270375],[-83.1257796,41.6878411],[-83.2474733,41.6878411],[-83.2474733,41.7536942],[-83.3737305,41.7536942],[-83.3737305,41.809276],[-83.3106019,41.809276],[-83.3106019,41.8716064],[-83.2474733,41.8716064],[-83.2474733,41.9361393],[-83.1843447,41.9361393],[-83.1843447,41.9960851],[-83.1207681,41.9960851],[-83.1207681,42.2464812],[-83.0589194,42.2464812],[-83.0589194,42.3089555],[-82.8685328,42.3089555],[-82.8685328,42.3717652],[-82.8072219,42.3717652],[-82.8072219,42.558553],[-82.7553745,42.558553],[-82.7553745,42.4954945],[-82.5599041,42.4954945],[-82.5599041,42.558553],[-82.4967755,42.558553],[-82.4967755,42.6833607],[-82.4328863,42.6833607],[-82.4328863,42.9342196],[-82.3700552,42.9342196],[-82.3700552,43.0648071],[-82.4328863,43.0648071],[-82.4328863,43.1917566],[-82.4947464,43.1917566],[-82.4947464,43.5034627],[-82.557133,43.5034627],[-82.557133,43.8160901],[-82.6197884,43.8160901],[-82.6197884,43.9422098],[-82.6839499,43.9422098],[-82.6839499,44.0022641],[-82.7465346,44.0022641],[-82.7465346,44.0670545],[-82.8708696,44.0670545],[-82.8708696,44.1291935],[-83.008517,44.1291935],[-83.008517,44.0664786],[-83.1336086,44.0664786],[-83.1336086,44.0053949],[-83.2414522,44.0053949],[-83.2414522,44.9962034],[-83.1806112,44.9962034],[-83.1806112,45.067302],[-83.2455172,45.067302],[-83.2455172,45.1287382],[-83.3065878,45.1287382],[-83.3065878,45.2551509],[-83.3706087,45.2551509],[-83.3706087,45.3165923],[-83.4325644,45.3165923],[-83.4325644,45.3792105],[-83.6178415,45.3792105],[-83.6178415,45.4419665],[-83.8084291,45.4419665],[-83.8084291,45.5036189],[-84.0550718,45.5036189],[-84.0550718,45.5647907],[-84.1235181,45.5647907],[-84.1235181,45.6287845],[-84.1807534,45.6287845],[-84.1807534,45.6914688],[-84.3111554,45.6914688],[-84.3111554,45.9337076],[-83.8209974,45.9337076],[-83.8209974,45.8725113],[-83.4968086,45.8725113],[-83.4968086,45.9337076],[-83.4338066,45.9337076],[-83.4338066,46.0016863],[-83.4962697,46.0016863],[-83.4962697,46.0668178],[-83.5599956,46.0668178],[-83.5599956,46.1261576],[-83.9954558,46.1261576],[-83.9954558,46.1931747],[-84.0591816,46.1931747],[-84.0591816,46.3814972],[-84.1152614,46.3814972],[-84.1152614,46.4953584],[-84.0591816,46.4953584],[-84.0591816,46.5682653],[-84.2579545,46.5682653],[-84.2579545,46.5051232],[-84.3071879,46.5051232],[-84.3071879,46.5682653],[-84.4415364,46.5682653],[-84.4415364,46.504525],[-84.9965729,46.504525],[-84.9965729,46.6842882],[-84.9298158,46.6842882],[-84.9298158,46.818077],[-85.3165894,46.818077],[-85.3165894,46.7535825],[-87.5562645,46.7535825],[-87.5562645,47.4407371],[-87.6825361,47.4407371],[-87.6825361,47.5035554],[-88.2560738,47.5035554],[-88.2560738,47.4433716],[-88.4417419,47.4433716],[-88.4417419,47.3789949],[-88.50683,47.3789949],[-88.50683,47.3153881],[-88.6312821,47.3153881],[-88.6312821,47.2539782],[-88.7569636,47.2539782],[-88.7569636,47.1934682],[-88.8838253,47.1934682],[-88.8838253,47.1284735],[-88.9434208,47.1284735],[-88.9434208,47.0662127],[-89.0708726,47.0662127],[-89.0708726,47.0026826],[-89.2565553,47.0026826],[-89.2565553,46.9410806],[-90.3677669,46.9410806],[-90.3677669,47.6844827],[-90.3069978,47.6844827],[-90.3069978,47.7460174],[-89.994859,47.7460174],[-89.994859,47.8082719],[-89.8048615,47.8082719],[-89.8048615,47.8700562],[-89.6797699,47.8700562],[-89.6797699,47.9339637],[-89.4933757,47.9339637],[-89.4933757,47.9957956],[-89.4284697,47.9957956],[-89.4284697,48.0656377],[-89.9932739,48.0656377],[-89.9932739,48.1282966],[-90.7455933,48.1282966],[-90.7455933,48.1893056],[-90.8087291,48.1893056],[-90.8087291,48.2522065],[-91.067763,48.2522065],[-91.067763,48.1916658],[-91.1946247,48.1916658],[-91.1946247,48.1279027],[-91.6814196,48.1279027],[-91.6814196,48.2525994],[-91.9321927,48.2525994],[-91.9321927,48.3142454],[-91.9929683,48.3142454],[-91.9929683,48.3780845],[-92.3189383,48.3780845],[-92.3189383,48.2529081],[-92.3732233,48.2529081],[-92.3732233,48.3153385],[-92.4322288,48.3153385],[-92.4322288,48.4411448],[-92.4977248,48.4411448],[-92.4977248,48.501781],[-92.5679413,48.501781],[-92.5679413,48.439579],[-92.6210462,48.439579],[-92.6210462,48.5650783],[-92.8086835,48.5650783],[-92.8086835,48.6286865],[-92.8086835,48.6267365],[-92.933185,48.6267365],[-92.933185,48.6922145],[-93.0051716,48.6922145],[-93.0051716,48.6282965],[-93.1225924,48.6282965],[-93.1225924,48.6922145],[-93.3190806,48.6922145],[-93.3190806,48.6267365],[-93.5049477,48.6267365],[-93.5049477,48.5635164],[-93.7474601,48.5635164],[-93.7474601,48.6267365],[-93.8135461,48.6267365],[-93.8135461,48.6898775],[-94.2453121,48.6898775],[-94.2453121,48.7554327],[-94.6183171,48.7554327],[-94.6183171,48.941036],[-94.6809018,48.941036],[-94.6809018,49.0029737],[-94.7441532,49.0029737],[-94.7441532,49.2536079],[-94.8084069,49.2536079],[-94.8084069,49.3784134],[-95.1192391,49.3784134],[-95.1192391,49.4425264],[-95.1934341,49.4425264],[-95.1934341,49.0035292],[-96.87069,49.0035292],[-96.87069,49.0656063],[-99.0049312,49.0656063],[-99.0049312,49.0050714],[-109.3699257,49.0050714],[-109.3699257,49.0668231],[-109.5058746,49.0668231],[-109.5058746,49.0050714],[-114.1830014,49.0050714],[-114.1830014,49.0687317],[-114.7578709,49.0687317],[-114.7578709,49.0050714],[-115.433731,49.0050714],[-115.433731,49.0671412],[-116.5062706,49.0671412],[-116.5062706,49.0050714],[-117.3089504,49.0050714],[-117.3089504,49.0659803],[-119.882945,49.0659803],[-119.882945,49.0050714],[-120.1208555,49.0050714],[-120.1208555,49.0678367],[-121.4451636,49.0678367],[-121.4451636,49.0050714],[-121.9311808,49.0050714],[-121.9311808,49.0656099],[-122.817484,49.0656099],[-122.817484,49.0029143],[-122.8795155,49.0029143],[-122.8795155,48.9347018],[-122.8174629,48.9347018],[-122.8174629,48.8101998],[-122.7538859,48.8101998],[-122.7538859,48.7533758],[-122.8712937,48.7533758],[-122.8712937,48.8153948],[-123.0055391,48.8153948],[-123.0055391,48.7529529],[-123.1296926,48.7529529],[-123.1296926,48.6902201],[-123.1838197,48.6902201],[-123.1838197,48.7529029],[-123.2549305,48.7529029]],[[-122.9341743,37.7521547],[-122.9347457,37.6842013],[-123.0679013,37.6849023],[-123.0673747,37.7475251],[-123.1292603,37.7478506],[-123.1286894,37.815685],[-123.0590687,37.8153192],[-123.0595947,37.7528143],[-122.9341743,37.7521547]],[[-71.6299464,41.2540893],[-71.4966465,41.2541393],[-71.4965596,41.122965],[-71.6298594,41.1229149],[-71.6299464,41.2540893]],[[-70.3184265,41.3775196],[-70.3183384,41.2448243],[-70.1906612,41.2448722],[-70.1906239,41.1886019],[-69.9336025,41.1886984],[-69.933729,41.3791941],[-69.9950664,41.3791712],[-69.995109,41.443159],[-70.0707828,41.4431307],[-70.0706972,41.3144915],[-70.2461667,41.3144258],[-70.2462087,41.3775467],[-70.3184265,41.3775196]],[[-68.9403374,43.9404062],[-68.6856948,43.9404977],[-68.6856475,43.8721797],[-68.7465405,43.8721577],[-68.7464976,43.8102529],[-68.8090782,43.8102304],[-68.8090343,43.746728],[-68.8773094,43.7467034],[-68.8773544,43.8117826],[-68.9402483,43.8117599],[-68.9403374,43.9404062]],[[-123.1291466,49.0645144],[-122.9954224,49.0645144],[-122.9954224,48.9343243],[-123.1291466,48.9343243],[-123.1291466,49.0645144]],[[-82.9407144,24.7535913],[-82.8719398,24.7535913],[-82.8719398,24.6905653],[-82.7446233,24.6905653],[-82.7446233,24.6214593],[-82.8088038,24.6214593],[-82.8088038,24.5594908],[-82.9407144,24.5594908],[-82.9407144,24.7535913]]]},{"id":"USGS-Scanned_Topographic","name":"USGS Topographic Maps","type":"tms","template":"http://{switch:a,b,c}.tile.openstreetmap.us/usgs_scanned_topos/{zoom}/{x}/{y}.png","polygon":[[[-125.990173,48.9962416],[-125.989419,47.9948396],[-123.9929739,47.9955062],[-123.9922429,47.0059202],[-125.988688,47.0052409],[-125.9879604,46.0015618],[-123.9939396,46.0022529],[-123.9925238,43.9961708],[-124.9931832,43.9958116],[-124.9918175,41.9942149],[-125.9851789,41.9938465],[-125.9838655,40.0076111],[-123.9833285,40.0083757],[-123.9814115,37.002615],[-122.21903,37.0033173],[-122.2184144,36.011671],[-122.020087,36.011751],[-122.0188591,33.9961766],[-119.9787757,33.9970206],[-119.9775867,31.9987658],[-114.0122833,32.00129],[-114.0116894,30.9862401],[-105.998294,30.9896679],[-105.9971419,28.9901065],[-102.0210506,28.9918418],[-102.0204916,28.00733],[-100.0062436,28.0082173],[-100.0051143,25.991909],[-98.0109067,25.9928035],[-98.0103613,25.0063461],[-97.0161086,25.0067957],[-97.016654,25.9932494],[-95.9824825,25.9937132],[-95.9835999,27.9891175],[-94.0200898,27.9899826],[-94.0206586,28.9918129],[-88.0156706,28.9944338],[-88.0162494,30.0038862],[-86.0277506,30.0047454],[-86.0271719,28.9953016],[-84.0187909,28.9961781],[-84.017095,25.9817708],[-81.9971976,25.9826768],[-81.9966618,25.0134917],[-84.0165592,25.0125783],[-84.0160068,24.0052745],[-80.0199985,24.007096],[-80.0245309,32.0161282],[-78.0066484,32.0169819],[-78.0072238,32.9894278],[-77.8807233,32.9894807],[-77.8813253,33.9955918],[-76.0115411,33.9963653],[-76.0121459,34.9952552],[-74.0068449,34.9960749],[-74.0099997,40.0084254],[-72.0013745,40.0091931],[-72.002019,40.9912464],[-69.8797398,40.9920457],[-69.8804173,42.00893],[-69.9927682,42.0088883],[-69.9934462,43.0105166],[-67.9845366,43.0112496],[-67.985224,44.0103812],[-65.9892568,44.0110975],[-65.9921237,47.9993584],[-70.006442,47.9980181],[-70.005708,47.0042007],[-72.023686,47.003514],[-72.0222508,45.0059846],[-78.0146667,45.0038705],[-78.0139662,44.0026998],[-80.029686,44.0019763],[-80.0290052,43.0122994],[-81.995479,43.011582],[-81.9982986,47.0042713],[-87.505706,47.0023972],[-87.5064535,48.0142702],[-88.0260889,48.0140968],[-88.026838,49.0086686],[-93.9981078,49.0067142],[-93.9988778,50.0086456],[-96.0138899,50.0079995],[-96.0131199,49.0060547],[-125.990173,48.9962416]],[[-160.5787616,22.5062947],[-160.5782192,21.4984647],[-159.0030121,21.499196],[-159.0027422,20.9951068],[-157.5083185,20.995803],[-157.5080519,20.4960241],[-155.966889,20.4967444],[-155.9674267,21.5028287],[-157.5044717,21.5021151],[-157.5047384,21.9984962],[-159.0090946,21.9978002],[-159.0093692,22.5070181],[-160.5787616,22.5062947]],[[-168.006102,68.9941463],[-168.0047628,68.0107853],[-165.4842481,68.0112562],[-165.4829337,67.0037303],[-168.0034485,67.0032389],[-168.002195,66.0017503],[-169.0087448,66.001546],[-169.0075381,64.9987675],[-168.0009882,64.9989798],[-167.9998282,63.9982374],[-164.9871288,63.9988964],[-164.9860062,62.9950845],[-167.9987057,62.9944019],[-167.9946035,59.0153692],[-162.5027857,59.0167799],[-162.5018149,58.0005815],[-160.0159024,58.0012389],[-160.0149725,57.000035],[-160.5054788,56.9999017],[-160.5045719,55.9968161],[-164.012195,55.9958373],[-164.0113186,55.00107],[-165.994782,55.0005023],[-165.9941266,54.2400584],[-168.0002944,54.2394734],[-168.0000986,54.0094921],[-170.0156134,54.0089011],[-170.0147683,53.0016446],[-171.9993636,53.0010487],[-171.9989488,52.4977745],[-176.0083239,52.4965566],[-176.0081186,52.2452555],[-178.000097,52.2446469],[-177.9992996,51.2554252],[-176.0073212,51.2560472],[-176.0075146,51.4980163],[-171.9981395,51.4992617],[-171.9985419,51.9985373],[-167.9984317,51.9997661],[-167.9994645,53.2560877],[-165.9932968,53.2566866],[-165.9939308,54.0100804],[-159.0067205,54.0121291],[-159.0075717,55.002502],[-158.0190709,55.0027849],[-158.0199473,55.9975094],[-151.9963213,55.9991902],[-151.9981536,57.9986536],[-151.500341,57.9987853],[-151.5012894,58.9919816],[-138.5159989,58.9953194],[-138.5150471,57.9986434],[-136.6872422,57.9991267],[-136.6863158,57.0016688],[-135.9973698,57.001856],[-135.9964667,56.0030544],[-134.6717732,56.003424],[-134.6708865,54.9969623],[-133.9956734,54.9971556],[-133.9948193,54.0031685],[-130.0044418,54.0043387],[-130.0070826,57.0000507],[-131.975877,56.9995156],[-131.9787378,59.9933094],[-138.0071813,59.991805],[-138.0082158,61.0125755],[-140.9874011,61.0118551],[-140.99984,71.0039309],[-154.5023956,71.0017377],[-154.5039632,71.9983391],[-157.499048,71.9978773],[-157.4974758,70.9982877],[-163.0233611,70.9973899],[-163.0218273,69.9707435],[-164.9730896,69.97041],[-164.9717003,68.994689],[-168.006102,68.9941463]],[[-168.5133204,62.8689586],[-168.5144423,63.8765677],[-172.0202755,63.8757975],[-172.0191536,62.8681608],[-168.5133204,62.8689586]],[[-170.9947111,59.9954089],[-170.995726,60.9969787],[-174.0045311,60.9962508],[-174.0035162,59.9946581],[-170.9947111,59.9954089]],[[-156.0717261,20.2854602],[-154.7940471,20.2860582],[-154.7933145,18.9029464],[-156.0709936,18.9023432],[-156.0717261,20.2854602]]]},{"id":"sjcgis.org-General_Basemap_WM","name":"Vector Streetmap for San Juan County WA","type":"tms","template":"http://sjcgis.org/arcgis/rest/services/Basemaps/General_Basemap_WM/MapServer/tile/{zoom}/{y}/{x}","description":"Public domain street and address data from the San Juan County, WA. Updated at least quarterly.","scaleExtent":[0,19],"polygon":[[[-123.274024,48.692975],[-123.007726,48.767256],[-123.007619,48.831577],[-122.783495,48.758416],[-122.693402,48.658522],[-122.767451,48.603606],[-122.744842,48.387083],[-123.248221,48.283531],[-123.114524,48.422614],[-123.219035,48.548575],[-123.274024,48.692975]]],"best":true},{"id":"Vejmidte_Denmark","name":"Vejmidte (Denmark)","type":"tms","template":"http://{switch:a,b,c}.tile.openstreetmap.dk/danmark/vejmidte/{zoom}/{x}/{y}.png","scaleExtent":[0,20],"polygon":[[[8.3743941,54.9551655],[8.3683809,55.4042149],[8.2103997,55.4039795],[8.2087314,55.4937345],[8.0502655,55.4924731],[8.0185123,56.7501399],[8.1819161,56.7509948],[8.1763274,57.0208898],[8.3413329,57.0219872],[8.3392467,57.1119574],[8.5054433,57.1123212],[8.5033923,57.2020499],[9.3316304,57.2027636],[9.3319079,57.2924835],[9.4978864,57.2919578],[9.4988593,57.3820608],[9.6649749,57.3811615],[9.6687295,57.5605591],[9.8351961,57.5596265],[9.8374896,57.6493322],[10.1725726,57.6462818],[10.1754245,57.7367768],[10.5118282,57.7330269],[10.5152095,57.8228945],[10.6834853,57.8207722],[10.6751613,57.6412021],[10.5077045,57.6433097],[10.5039992,57.5535088],[10.671038,57.5514113],[10.6507805,57.1024538],[10.4857673,57.1045138],[10.4786236,56.9249051],[10.3143981,56.9267573],[10.3112341,56.8369269],[10.4750295,56.83509],[10.4649016,56.5656681],[10.9524239,56.5589761],[10.9479249,56.4692243],[11.1099335,56.4664675],[11.1052639,56.376833],[10.9429901,56.3795284],[10.9341235,56.1994768],[10.7719685,56.2020244],[10.7694751,56.1120103],[10.6079695,56.1150259],[10.4466742,56.116717],[10.2865948,56.118675],[10.2831527,56.0281851],[10.4439274,56.0270388],[10.4417713,55.7579243],[10.4334961,55.6693533],[10.743814,55.6646861],[10.743814,55.5712253],[10.8969041,55.5712253],[10.9051793,55.3953852],[11.0613726,55.3812841],[11.0593038,55.1124061],[11.0458567,55.0318621],[11.2030844,55.0247474],[11.2030844,55.117139],[11.0593038,55.1124061],[11.0613726,55.3812841],[11.0789572,55.5712253],[10.8969041,55.5712253],[10.9258671,55.6670198],[10.743814,55.6646861],[10.7562267,55.7579243],[10.4417713,55.7579243],[10.4439274,56.0270388],[10.4466742,56.116717],[10.6079695,56.1150259],[10.6052053,56.0247462],[10.9258671,56.0201215],[10.9197132,55.9309388],[11.0802782,55.92792],[11.0858066,56.0178284],[11.7265047,56.005058],[11.7319981,56.0952142],[12.0540333,56.0871256],[12.0608477,56.1762576],[12.7023469,56.1594405],[12.6611131,55.7114318],[12.9792318,55.7014026],[12.9612912,55.5217294],[12.3268659,55.5412096],[12.3206071,55.4513655],[12.4778226,55.447067],[12.4702432,55.3570479],[12.6269738,55.3523837],[12.6200898,55.2632576],[12.4627339,55.26722],[12.4552949,55.1778223],[12.2987046,55.1822303],[12.2897344,55.0923641],[12.6048608,55.0832904],[12.5872011,54.9036285],[12.2766618,54.9119031],[12.2610181,54.7331602],[12.1070691,54.7378161],[12.0858621,54.4681655],[11.7794953,54.4753579],[11.7837381,54.5654783],[11.1658525,54.5782155],[11.1706443,54.6686508],[10.8617173,54.6733956],[10.8651245,54.7634667],[10.7713646,54.7643888],[10.7707276,54.7372807],[10.7551428,54.7375776],[10.7544039,54.7195666],[10.7389074,54.7197588],[10.7384368,54.7108482],[10.7074486,54.7113045],[10.7041094,54.6756741],[10.5510973,54.6781698],[10.5547184,54.7670245],[10.2423994,54.7705935],[10.2459845,54.8604673],[10.0902268,54.8622134],[10.0873731,54.7723851],[9.1555798,54.7769557],[9.1562752,54.8675369],[8.5321973,54.8663765],[8.531432,54.95516],[8.3743941,54.9551655]],[[11.4577738,56.819554],[11.7849181,56.8127385],[11.7716715,56.6332796],[11.4459621,56.6401087],[11.4577738,56.819554]],[[11.3274736,57.3612962],[11.3161808,57.1818004],[11.1508692,57.1847276],[11.1456628,57.094962],[10.8157703,57.1001693],[10.8290599,57.3695272],[11.3274736,57.3612962]],[[11.5843266,56.2777928],[11.5782882,56.1880397],[11.7392309,56.1845765],[11.7456428,56.2743186],[11.5843266,56.2777928]],[[14.6825922,55.3639405],[14.8395247,55.3565231],[14.8263755,55.2671261],[15.1393406,55.2517359],[15.1532015,55.3410836],[15.309925,55.3330556],[15.295719,55.2437356],[15.1393406,55.2517359],[15.1255631,55.1623802],[15.2815819,55.1544167],[15.2535578,54.9757646],[14.6317464,55.0062496],[14.6825922,55.3639405]]],"terms_url":"http://wiki.openstreetmap.org/wiki/Vejmidte","terms_text":"Danish municipalities"},{"id":"wien.gv.at-labels","name":"Vienna: Beschriftungen (annotations)","type":"tms","template":"https://maps.wien.gv.at/wmts/beschriftung/normal/google3857/{zoom}/{y}/{x}.png","scaleExtent":[12,19],"polygon":[[[16.17,48.1],[16.17,48.33],[16.58,48.33],[16.58,48.1],[16.17,48.1]]],"terms_url":"https://data.wien.gv.at/","terms_text":"Stadt Wien"},{"id":"wien.gv.at-gp","name":"Vienna: Mehrzweckkarte (general purpose)","type":"tms","template":"https://maps.wien.gv.at/wmts/fmzk/pastell/google3857/{zoom}/{y}/{x}.jpeg","scaleExtent":[10,19],"polygon":[[[16.17,48.1],[16.17,48.33],[16.58,48.33],[16.58,48.1],[16.17,48.1]]],"terms_url":"https://data.wien.gv.at/","terms_text":"Stadt Wien"},{"id":"wien.gv.at-aerial_image","name":"Vienna: Orthofoto (aerial image)","type":"tms","template":"https://maps.wien.gv.at/wmts/lb/farbe/google3857/{zoom}/{y}/{x}.jpeg","scaleExtent":[10,19],"polygon":[[[16.17,48.1],[16.17,48.33],[16.58,48.33],[16.58,48.1],[16.17,48.1]]],"terms_url":"https://data.wien.gv.at/","terms_text":"Stadt Wien"}];
18962 var presets = {"aerialway":{"fields":["aerialway"],"geometry":["point","vertex","line"],"tags":{"aerialway":"*"},"terms":["ski lift","funifor","funitel"],"searchable":false,"name":"Aerialway"},"aeroway":{"icon":"airport","fields":["aeroway"],"geometry":["point","vertex","line","area"],"tags":{"aeroway":"*"},"searchable":false,"name":"Aeroway"},"amenity":{"fields":["amenity"],"geometry":["point","vertex","area"],"tags":{"amenity":"*"},"searchable":false,"name":"Amenity"},"highway":{"fields":["highway"],"geometry":["point","vertex","line","area"],"tags":{"highway":"*"},"searchable":false,"name":"Highway"},"place":{"fields":["place"],"geometry":["point","vertex","area"],"tags":{"place":"*"},"searchable":false,"name":"Place"},"power":{"geometry":["point","vertex","line","area"],"tags":{"power":"*"},"fields":["power"],"searchable":false,"name":"Power"},"railway":{"fields":["railway"],"geometry":["point","vertex","line","area"],"tags":{"railway":"*"},"searchable":false,"name":"Railway"},"roundabout":{"geometry":["vertex","line"],"tags":{"junction":"roundabout"},"name":"Roundabout","searchable":false},"waterway":{"fields":["waterway"],"geometry":["point","vertex","line","area"],"tags":{"waterway":"*"},"searchable":false,"name":"Waterway"},"address":{"fields":["address"],"geometry":["point"],"tags":{"addr:housenumber":"*"},"addTags":{},"removeTags":{},"matchScore":0.2,"name":"Address"},"advertising/billboard":{"fields":["parallel_direction","lit"],"geometry":["point","vertex","line"],"tags":{"advertising":"billboard"},"name":"Billboard"},"aerialway/cable_car":{"geometry":["line"],"terms":["tramway","ropeway"],"fields":["aerialway/occupancy","aerialway/capacity","aerialway/duration","aerialway/heating"],"tags":{"aerialway":"cable_car"},"name":"Cable Car"},"aerialway/chair_lift":{"geometry":["line"],"fields":["aerialway/occupancy","aerialway/capacity","aerialway/duration","aerialway/bubble","aerialway/heating"],"tags":{"aerialway":"chair_lift"},"name":"Chair Lift"},"aerialway/gondola":{"geometry":["line"],"fields":["aerialway/occupancy","aerialway/capacity","aerialway/duration","aerialway/bubble","aerialway/heating"],"tags":{"aerialway":"gondola"},"name":"Gondola"},"aerialway/magic_carpet":{"geometry":["line"],"fields":["aerialway/capacity","aerialway/duration","aerialway/heating"],"tags":{"aerialway":"magic_carpet"},"name":"Magic Carpet Lift"},"aerialway/platter":{"geometry":["line"],"terms":["button lift","poma lift"],"fields":["aerialway/capacity","aerialway/duration"],"tags":{"aerialway":"platter"},"name":"Platter Lift"},"aerialway/pylon":{"geometry":["point","vertex"],"fields":["ref"],"tags":{"aerialway":"pylon"},"name":"Aerialway Pylon"},"aerialway/rope_tow":{"geometry":["line"],"terms":["handle tow","bugel lift"],"fields":["aerialway/capacity","aerialway/duration"],"tags":{"aerialway":"rope_tow"},"name":"Rope Tow Lift"},"aerialway/station":{"geometry":["point","vertex"],"fields":["aerialway/access","aerialway/summer/access","elevation"],"tags":{"aerialway":"station"},"name":"Aerialway Station"},"aerialway/t-bar":{"geometry":["line"],"fields":["aerialway/capacity","aerialway/duration"],"tags":{"aerialway":"t-bar"},"name":"T-bar Lift"},"aeroway/aerodrome":{"icon":"airport","geometry":["point","area"],"terms":["airplane","airport","aerodrome"],"fields":["ref","iata","icao","operator"],"tags":{"aeroway":"aerodrome"},"name":"Airport"},"aeroway/apron":{"icon":"airport","geometry":["area"],"terms":["ramp"],"fields":["ref","surface"],"tags":{"aeroway":"apron"},"name":"Apron"},"aeroway/gate":{"icon":"airport","geometry":["point"],"fields":["ref"],"tags":{"aeroway":"gate"},"name":"Airport gate"},"aeroway/hangar":{"geometry":["area"],"fields":["building_area"],"tags":{"aeroway":"hangar"},"name":"Hangar"},"aeroway/helipad":{"icon":"heliport","geometry":["point","area"],"terms":["helicopter","helipad","heliport"],"tags":{"aeroway":"helipad"},"name":"Helipad"},"aeroway/runway":{"geometry":["line","area"],"terms":["landing strip"],"fields":["ref","surface","length","width"],"tags":{"aeroway":"runway"},"name":"Runway"},"aeroway/taxiway":{"geometry":["line"],"fields":["ref","surface"],"tags":{"aeroway":"taxiway"},"name":"Taxiway"},"aeroway/terminal":{"geometry":["point","area"],"terms":["airport","aerodrome"],"fields":["operator","building_area"],"tags":{"aeroway":"terminal"},"name":"Airport terminal"},"amenity/register_office":{"icon":"town-hall","fields":["address","building_area","opening_hours","operator"],"geometry":["point","area"],"terms":[],"tags":{"amenity":"register_office"},"name":"Register Office","searchable":false},"amenity/swimming_pool":{"icon":"swimming","geometry":["point","vertex","area"],"tags":{"amenity":"swimming_pool"},"name":"Swimming Pool","searchable":false},"amenity/arts_centre":{"icon":"theatre","fields":["address","building_area","opening_hours"],"geometry":["point","area"],"terms":[],"tags":{"amenity":"arts_centre"},"name":"Arts Center"},"amenity/atm":{"icon":"bank","fields":["operator","currency_multi","drive_through"],"geometry":["point","vertex"],"terms":["money","cash","machine"],"tags":{"amenity":"atm"},"name":"ATM"},"amenity/bank":{"icon":"bank","fields":["atm","operator","address","building_area","opening_hours","drive_through"],"geometry":["point","area"],"terms":["credit union","check","deposit","fund","investment","repository","reserve","safe","savings","stock","treasury","trust","vault"],"tags":{"amenity":"bank"},"name":"Bank"},"amenity/bar":{"icon":"bar","fields":["operator","address","building_area","opening_hours","smoking"],"geometry":["point","area"],"terms":["dive","beer","bier","booze"],"tags":{"amenity":"bar"},"name":"Bar"},"amenity/bbq":{"fields":["covered","fuel"],"geometry":["point"],"terms":["bbq","grill"],"tags":{"amenity":"bbq"},"name":"Barbecue/Grill"},"amenity/bench":{"fields":["backrest"],"geometry":["point","vertex","line"],"terms":["seat"],"tags":{"amenity":"bench"},"name":"Bench"},"amenity/bicycle_parking":{"icon":"bicycle","fields":["bicycle_parking","capacity","operator","covered","access_simple"],"geometry":["point","vertex","area"],"terms":["bike"],"tags":{"amenity":"bicycle_parking"},"name":"Bicycle Parking"},"amenity/bicycle_rental":{"icon":"bicycle","fields":["capacity","network","operator"],"geometry":["point","vertex","area"],"terms":["bike"],"tags":{"amenity":"bicycle_rental"},"name":"Bicycle Rental"},"amenity/bicycle_repair_station":{"icon":"bicycle","fields":["operator","brand","opening_hours","fee","service/bicycle"],"geometry":["point","vertex","area"],"terms":["bike","repair","chain","pump"],"tags":{"amenity":"bicycle_repair_station"},"name":"Bicycle Repair Tool Stand"},"amenity/biergarten":{"icon":"beer","fields":["address","building_area","opening_hours","smoking"],"geometry":["point","area"],"tags":{"amenity":"biergarten"},"terms":["beer","bier","booze"],"name":"Beer Garden"},"amenity/boat_rental":{"fields":["operator"],"geometry":["point","area"],"tags":{"amenity":"boat_rental"},"name":"Boat Rental"},"amenity/bureau_de_change":{"icon":"bank","fields":["operator","currency_multi"],"geometry":["point","vertex"],"terms":["bureau de change","money changer"],"tags":{"amenity":"bureau_de_change"},"name":"Currency Exchange"},"amenity/bus_station":{"icon":"bus","fields":["building_area","operator"],"geometry":["point","area"],"tags":{"amenity":"bus_station"},"name":"Bus Station"},"amenity/cafe":{"icon":"cafe","fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"geometry":["point","area"],"terms":["bistro","coffee","tea"],"tags":{"amenity":"cafe"},"name":"Cafe"},"amenity/car_rental":{"icon":"car","fields":["operator"],"geometry":["point","area"],"tags":{"amenity":"car_rental"},"name":"Car Rental"},"amenity/car_sharing":{"icon":"car","fields":["operator","capacity"],"geometry":["point","area"],"tags":{"amenity":"car_sharing"},"name":"Car Sharing"},"amenity/car_wash":{"icon":"car","fields":["address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"amenity":"car_wash"},"name":"Car Wash"},"amenity/casino":{"fields":["operator","address","building_area","opening_hours","smoking"],"geometry":["point","area"],"terms":["gambling","roulette","craps","poker","blackjack"],"tags":{"amenity":"casino"},"name":"Casino"},"amenity/charging_station":{"icon":"car","fields":["operator","capacity"],"geometry":["point","area"],"tags":{"amenity":"charging_station"},"terms":["EV","Electric Vehicle","Supercharger"],"name":"Charging Station"},"amenity/childcare":{"icon":"school","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["daycare","orphanage","playgroup"],"tags":{"amenity":"childcare"},"name":"Nursery/Childcare"},"amenity/cinema":{"icon":"cinema","fields":["address","building_area","opening_hours"],"geometry":["point","area"],"terms":["drive-in","film","flick","movie","theater","picture","show","screen"],"tags":{"amenity":"cinema"},"name":"Cinema"},"amenity/clinic":{"icon":"hospital","fields":["address","building_area","opening_hours"],"geometry":["point","area"],"terms":["medical","urgentcare"],"tags":{"amenity":"clinic"},"name":"Clinic"},"amenity/clock":{"fields":["support","display","visibility","date"],"geometry":["point","vertex"],"tags":{"amenity":"clock"},"name":"Clock"},"amenity/college":{"icon":"college","fields":["operator","address"],"geometry":["point","area"],"terms":["university"],"tags":{"amenity":"college"},"name":"College Grounds"},"amenity/community_centre":{"icon":"town-hall","fields":["operator","address","building_area"],"geometry":["point","area"],"terms":["event","hall"],"tags":{"amenity":"community_centre"},"name":"Community Center"},"amenity/compressed_air":{"icon":"car","geometry":["point","area"],"tags":{"amenity":"compressed_air"},"name":"Compressed Air"},"amenity/courthouse":{"icon":"town-hall","fields":["operator","address","building_area"],"geometry":["point","area"],"tags":{"amenity":"courthouse"},"name":"Courthouse"},"amenity/coworking_space":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","area"],"terms":["coworking","office"],"tags":{"amenity":"coworking_space"},"name":"Coworking Space"},"amenity/dentist":{"icon":"dentist","fields":["address","building_area","opening_hours"],"geometry":["point","area"],"terms":["tooth","teeth"],"tags":{"amenity":"dentist"},"name":"Dentist"},"amenity/doctors":{"icon":"hospital","fields":["address","building_area","opening_hours"],"geometry":["point","area"],"terms":["medic*"],"tags":{"amenity":"doctors"},"name":"Doctor"},"amenity/dojo":{"icon":"pitch","fields":["sport","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["martial arts","dojang"],"tags":{"amenity":"dojo"},"name":"Dojo / Martial Arts Academy"},"amenity/drinking_water":{"icon":"water","geometry":["point"],"tags":{"amenity":"drinking_water"},"terms":["fountain","potable"],"name":"Drinking Water"},"amenity/embassy":{"icon":"embassy","fields":["country","address","building_area"],"geometry":["point","area"],"tags":{"amenity":"embassy"},"name":"Embassy"},"amenity/fast_food":{"icon":"fast-food","fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"geometry":["point","area"],"tags":{"amenity":"fast_food"},"terms":["restaurant","takeaway"],"name":"Fast Food"},"amenity/ferry_terminal":{"icon":"ferry","fields":["network","operator","address","building_area"],"geometry":["point","vertex","area"],"terms":[],"tags":{"amenity":"ferry_terminal"},"name":"Ferry Terminal"},"amenity/fire_station":{"icon":"fire-station","fields":["operator","address","building_area"],"geometry":["point","area"],"terms":[],"tags":{"amenity":"fire_station"},"name":"Fire Station"},"amenity/fountain":{"geometry":["point","area"],"tags":{"amenity":"fountain"},"name":"Fountain"},"amenity/fuel":{"icon":"fuel","fields":["operator","address","opening_hours","fuel_multi"],"geometry":["point","area"],"terms":["petrol","fuel","gasoline","propane","diesel","lng","cng","biodiesel"],"tags":{"amenity":"fuel"},"name":"Gas Station"},"amenity/grave_yard":{"icon":"cemetery","fields":["religion","denomination"],"geometry":["point","area"],"tags":{"amenity":"grave_yard"},"name":"Graveyard"},"amenity/grit_bin":{"fields":["access_simple"],"geometry":["point","vertex"],"tags":{"amenity":"grit_bin"},"terms":["salt","sand"],"name":"Grit Bin"},"amenity/hospital":{"icon":"hospital","fields":["operator","address","emergency"],"geometry":["point","area"],"terms":["clinic","doctor","emergency room","health service","hospice","infirmary","institution","nursing home","sanatorium","sanitarium","sick","surgery","ward"],"tags":{"amenity":"hospital"},"name":"Hospital Grounds"},"amenity/hunting_stand":{"geometry":["point","vertex","area"],"terms":[],"tags":{"amenity":"hunting_stand"},"name":"Hunting Stand"},"amenity/ice_cream":{"icon":"ice-cream","fields":["address","building_area","opening_hours","takeaway","delivery"],"geometry":["point","area"],"terms":["gelato","sorbet","sherbet","frozen","yogurt"],"tags":{"amenity":"ice_cream"},"name":"Ice Cream Shop"},"amenity/internet_cafe":{"fields":["operator","address","building_area","opening_hours","smoking"],"geometry":["point","area"],"terms":["cybercafe","taxiphone","teleboutique","coffee","cafe","net","lanhouse"],"tags":{"amenity":"internet_cafe"},"name":"Internet Cafe"},"amenity/kindergarten":{"icon":"school","fields":["operator","address"],"geometry":["point","area"],"terms":["kindergarden","pre-school"],"tags":{"amenity":"kindergarten"},"name":"Preschool/Kindergarten Grounds"},"amenity/library":{"icon":"library","fields":["operator","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["book"],"tags":{"amenity":"library"},"name":"Library"},"amenity/marketplace":{"fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"amenity":"marketplace"},"name":"Marketplace"},"amenity/motorcycle_parking":{"icon":"scooter","fields":["capacity","operator","covered","access_simple"],"geometry":["point","vertex","area"],"tags":{"amenity":"motorcycle_parking"},"name":"Motorcycle Parking"},"amenity/nightclub":{"icon":"bar","fields":["operator","address","building_area","opening_hours","smoking"],"geometry":["point","area"],"tags":{"amenity":"nightclub"},"terms":["disco*","night club","dancing","dance club"],"name":"Nightclub"},"amenity/parking_entrance":{"icon":"entrance","fields":["access_simple","ref"],"geometry":["vertex"],"tags":{"amenity":"parking_entrance"},"name":"Parking Garage Entrance/Exit"},"amenity/parking_space":{"fields":["capacity"],"geometry":["point","vertex","area"],"terms":[],"tags":{"amenity":"parking_space"},"name":"Parking Space"},"amenity/parking":{"icon":"parking","fields":["operator","parking","capacity","fee","access_simple","supervised","park_ride","surface","maxstay","address"],"geometry":["point","vertex","area"],"tags":{"amenity":"parking"},"terms":[],"name":"Car Parking"},"amenity/pharmacy":{"icon":"pharmacy","fields":["operator","address","building_area","opening_hours","drive_through"],"geometry":["point","area"],"tags":{"amenity":"pharmacy"},"terms":["drug*","med*","prescription"],"name":"Pharmacy"},"amenity/place_of_worship":{"icon":"place-of-worship","fields":["religion","denomination","address","building_area"],"geometry":["point","area"],"terms":["abbey","basilica","bethel","cathedral","chancel","chantry","chapel","church","fold","house of God","house of prayer","house of worship","minster","mission","mosque","oratory","parish","sacellum","sanctuary","shrine","synagogue","tabernacle","temple"],"tags":{"amenity":"place_of_worship"},"name":"Place of Worship"},"amenity/place_of_worship/buddhist":{"icon":"place-of-worship","fields":["denomination","building_area","address"],"geometry":["point","area"],"terms":["stupa","vihara","monastery","temple","pagoda","zendo","dojo"],"tags":{"amenity":"place_of_worship","religion":"buddhist"},"name":"Buddhist Temple"},"amenity/place_of_worship/christian":{"icon":"religious-christian","fields":["denomination","building_area","address"],"geometry":["point","area"],"terms":["christian","abbey","basilica","bethel","cathedral","chancel","chantry","chapel","fold","house of God","house of prayer","house of worship","minster","mission","oratory","parish","sacellum","sanctuary","shrine","tabernacle","temple"],"tags":{"amenity":"place_of_worship","religion":"christian"},"name":"Church"},"amenity/place_of_worship/jewish":{"icon":"religious-jewish","fields":["denomination","building_area","address"],"geometry":["point","area"],"terms":["jewish"],"tags":{"amenity":"place_of_worship","religion":"jewish"},"name":"Synagogue"},"amenity/place_of_worship/muslim":{"icon":"religious-muslim","fields":["denomination","building_area","address"],"geometry":["point","area"],"terms":["muslim"],"tags":{"amenity":"place_of_worship","religion":"muslim"},"name":"Mosque"},"amenity/planetarium":{"icon":"museum","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["museum","astronomy","observatory"],"tags":{"amenity":"planetarium"},"name":"Planetarium"},"amenity/police":{"icon":"police","fields":["operator","address","building_area"],"geometry":["point","area"],"terms":["badge","constable","constabulary","cop","detective","fed","law","enforcement","officer","patrol"],"tags":{"amenity":"police"},"name":"Police"},"amenity/post_box":{"icon":"post","fields":["operator","collection_times","drive_through","ref"],"geometry":["point","vertex"],"tags":{"amenity":"post_box"},"terms":["letter","post"],"name":"Mailbox"},"amenity/post_office":{"icon":"post","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["letter","mail"],"tags":{"amenity":"post_office"},"name":"Post Office"},"amenity/prison":{"icon":"prison","fields":["operator","address"],"geometry":["point","area"],"terms":["cell","jail"],"tags":{"amenity":"prison"},"name":"Prison Grounds"},"amenity/pub":{"icon":"beer","fields":["address","building_area","opening_hours","smoking"],"geometry":["point","area"],"tags":{"amenity":"pub"},"terms":["dive","beer","bier","booze"],"name":"Pub"},"amenity/public_bookcase":{"icon":"library","fields":["name","operator","capacity","website"],"geometry":["point","area"],"terms":["library","bookcrossing"],"tags":{"amenity":"public_bookcase"},"name":"Public Bookcase"},"amenity/ranger_station":{"fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["visitor center","visitor centre","permit center","permit centre","backcountry office","warden office","warden center"],"tags":{"amenity":"ranger_station"},"name":"Ranger Station"},"amenity/recycling_centre":{"icon":"waste-basket","fields":["operator","address","opening_hours","recycling_accepts"],"geometry":["point","area"],"terms":["bottle","can","dump","glass","garbage","rubbish","scrap","trash"],"tags":{"amenity":"recycling","recycling_type":"centre"},"name":"Recycling Center"},"amenity/recycling":{"icon":"waste-basket","fields":["recycling_type","recycling_accepts","collection_times"],"geometry":["point","area"],"terms":["bin","can","bottle","glass","garbage","rubbish","scrap","trash"],"tags":{"amenity":"recycling"},"name":"Recycling"},"amenity/restaurant":{"icon":"restaurant","fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"geometry":["point","area"],"terms":["bar","breakfast","cafe","café","canteen","coffee","dine","dining","dinner","drive-in","eat","grill","lunch","table"],"tags":{"amenity":"restaurant"},"name":"Restaurant"},"amenity/sanitary_dump_station":{"fields":["operator","access_toilets","fee","water_point"],"geometry":["point","vertex","area"],"terms":["Motor Home","Camper","Sanitary","Dump Station","Elsan","CDP","CTDP","Chemical Toilet"],"tags":{"amenity":"sanitary_dump_station"},"name":"RV Toilet Disposal"},"amenity/school":{"icon":"school","fields":["operator","address"],"geometry":["point","area"],"terms":["academy","elementary school","middle school","high school"],"tags":{"amenity":"school"},"name":"School Grounds"},"amenity/shelter":{"fields":["shelter_type","bin"],"geometry":["point","vertex","area"],"terms":["lean-to","gazebo","picnic"],"tags":{"amenity":"shelter"},"name":"Shelter"},"amenity/social_facility":{"fields":["operator","address","building_area","opening_hours","wheelchair","social_facility_for"],"geometry":["point","area"],"terms":[],"tags":{"amenity":"social_facility"},"name":"Social Facility"},"amenity/social_facility/food_bank":{"fields":["operator","address","building_area","opening_hours","social_facility_for"],"geometry":["point","area"],"terms":[],"tags":{"amenity":"social_facility","social_facility":"food_bank"},"name":"Food Bank"},"amenity/social_facility/group_home":{"fields":["operator","address","building_area","opening_hours","wheelchair","social_facility_for"],"geometry":["point","area"],"terms":["old","senior","living"],"tags":{"amenity":"social_facility","social_facility":"group_home","social_facility:for":"senior"},"name":"Elderly Group Home"},"amenity/social_facility/homeless_shelter":{"fields":["operator","address","building_area","opening_hours","wheelchair","social_facility_for"],"geometry":["point","area"],"terms":["houseless","unhoused","displaced"],"tags":{"amenity":"social_facility","social_facility":"shelter","social_facility:for":"homeless"},"name":"Homeless Shelter"},"amenity/studio":{"icon":"music","fields":["studio","address","building_area"],"geometry":["point","area"],"terms":["recording","radio","television"],"tags":{"amenity":"studio"},"name":"Studio"},"amenity/taxi":{"icon":"car","fields":["operator","capacity"],"geometry":["point","vertex","area"],"terms":["cab"],"tags":{"amenity":"taxi"},"name":"Taxi Stand"},"amenity/telephone":{"icon":"telephone","geometry":["point","vertex"],"tags":{"amenity":"telephone"},"terms":["phone"],"name":"Telephone"},"amenity/theatre":{"icon":"theatre","fields":["operator","address","building_area"],"geometry":["point","area"],"terms":["theatre","performance","play","musical"],"tags":{"amenity":"theatre"},"name":"Theater"},"amenity/toilets":{"icon":"toilets","fields":["toilets/disposal","operator","building_area","access_toilets","gender","fee","diaper"],"geometry":["point","vertex","area"],"terms":["bathroom","restroom","outhouse","privy","head","lavatory","latrine","water closet","WC","W.C."],"tags":{"amenity":"toilets"},"name":"Toilets"},"amenity/townhall":{"icon":"town-hall","fields":["operator","address","building_area"],"geometry":["point","area"],"terms":["village","city","government","courthouse","municipal"],"tags":{"amenity":"townhall"},"name":"Town Hall"},"amenity/university":{"icon":"college","fields":["operator","address"],"geometry":["point","area"],"terms":["college"],"tags":{"amenity":"university"},"name":"University Grounds"},"amenity/vending_machine/cigarettes":{"fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["cigarette"],"tags":{"amenity":"vending_machine","vending":"cigarettes"},"name":"Cigarette Vending Machine"},"amenity/vending_machine/condoms":{"fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["condom"],"tags":{"amenity":"vending_machine","vending":"condoms"},"name":"Condom Vending Machine"},"amenity/vending_machine/drinks":{"fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["drink","soda","beverage","juice","pop"],"tags":{"amenity":"vending_machine","vending":"drinks"},"name":"Drink Vending Machine"},"amenity/vending_machine/excrement_bags":{"fields":["operator","fee","bin","payment_multi","currency_multi"],"geometry":["point"],"terms":["excrement bags","poop","dog","animal"],"tags":{"amenity":"vending_machine","vending":"excrement_bags"},"name":"Excrement Bag Vending Machine"},"amenity/vending_machine/news_papers":{"fields":["operator","fee","payment_multi","currency_multi"],"geometry":["point"],"terms":["newspaper"],"tags":{"amenity":"vending_machine","vending":"news_papers"},"name":"Newspaper Vending Machine"},"amenity/vending_machine/parcel_pickup_dropoff":{"fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["parcel","mail","pickup"],"tags":{"amenity":"vending_machine","vending":"parcel_pickup;parcel_mail_in"},"name":"Parcel Pickup/Dropoff Vending Machine"},"amenity/vending_machine/parking_tickets":{"fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["parking","ticket"],"tags":{"amenity":"vending_machine","vending":"parking_tickets"},"name":"Parking Ticket Vending Machine"},"amenity/vending_machine/public_transport_tickets":{"fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["bus","train","ferry","rail","ticket","transportation"],"tags":{"amenity":"vending_machine","vending":"public_transport_tickets"},"name":"Transit Ticket Vending Machine"},"amenity/vending_machine/sweets":{"fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["candy","gum","chip","pretzel","cookie","cracker"],"tags":{"amenity":"vending_machine","vending":"sweets"},"name":"Snack Vending Machine"},"amenity/vending_machine/vending_machine":{"fields":["vending","operator","payment_multi","currency_multi"],"geometry":["point"],"terms":[],"tags":{"amenity":"vending_machine"},"name":"Vending Machine"},"amenity/veterinary":{"icon":"dog-park","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["pet clinic","veterinarian","animal hospital","pet doctor"],"tags":{"amenity":"veterinary"},"name":"Veterinary"},"amenity/waste_basket":{"icon":"waste-basket","fields":["collection_times"],"geometry":["point","vertex","area"],"tags":{"amenity":"waste_basket"},"terms":["bin","garbage","rubbish","litter","trash"],"name":"Waste Basket"},"amenity/waste_disposal":{"icon":"waste-basket","fields":["collection_times"],"geometry":["point","vertex","area"],"tags":{"amenity":"waste_disposal"},"terms":["garbage","rubbish","litter","trash"],"name":"Garbage Dumpster"},"amenity/waste_transfer_station":{"icon":"waste-basket","fields":["operator","address","opening_hours"],"geometry":["point","area"],"terms":["dump","garbage","recycling","rubbish","scrap","trash"],"tags":{"amenity":"waste_transfer_station"},"name":"Waste Transfer Station"},"amenity/water_point":{"icon":"water","geometry":["area","vertex","point"],"tags":{"amenity":"water_point"},"name":"RV Drinking Water"},"area":{"name":"Area","tags":{"area":"yes"},"geometry":["area"],"matchScore":0.1},"area/highway":{"fields":["area/highway"],"geometry":["area"],"tags":{"area:highway":"*"},"name":"Road Surface"},"barrier":{"icon":"roadblock","geometry":["point","vertex","line","area"],"tags":{"barrier":"*"},"fields":["barrier"],"name":"Barrier"},"barrier/entrance":{"icon":"entrance","geometry":["vertex"],"tags":{"barrier":"entrance"},"name":"Entrance","searchable":false},"barrier/block":{"icon":"roadblock","fields":["access"],"geometry":["point","vertex"],"tags":{"barrier":"block"},"name":"Block"},"barrier/bollard":{"icon":"roadblock","fields":["access"],"geometry":["point","vertex","line"],"tags":{"barrier":"bollard"},"name":"Bollard"},"barrier/cattle_grid":{"icon":"prison","geometry":["vertex"],"tags":{"barrier":"cattle_grid"},"name":"Cattle Grid"},"barrier/city_wall":{"icon":"prison","geometry":["line","area"],"tags":{"barrier":"city_wall"},"name":"City Wall"},"barrier/cycle_barrier":{"icon":"roadblock","fields":["access"],"geometry":["vertex"],"tags":{"barrier":"cycle_barrier"},"name":"Cycle Barrier"},"barrier/ditch":{"icon":"roadblock","geometry":["line","area"],"tags":{"barrier":"ditch"},"name":"Trench"},"barrier/fence":{"icon":"prison","geometry":["line"],"tags":{"barrier":"fence"},"name":"Fence"},"barrier/gate":{"icon":"prison","fields":["access"],"geometry":["point","vertex","line"],"tags":{"barrier":"gate"},"name":"Gate"},"barrier/hedge":{"geometry":["line","area"],"tags":{"barrier":"hedge"},"name":"Hedge"},"barrier/kissing_gate":{"icon":"prison","fields":["access"],"geometry":["vertex"],"tags":{"barrier":"kissing_gate"},"name":"Kissing Gate"},"barrier/lift_gate":{"icon":"roadblock","fields":["access"],"geometry":["point","vertex"],"tags":{"barrier":"lift_gate"},"name":"Lift Gate"},"barrier/retaining_wall":{"geometry":["line","area"],"tags":{"barrier":"retaining_wall"},"name":"Retaining Wall"},"barrier/stile":{"icon":"roadblock","fields":["access"],"geometry":["point","vertex"],"tags":{"barrier":"stile"},"name":"Stile"},"barrier/toll_booth":{"icon":"roadblock","fields":["access"],"geometry":["vertex"],"tags":{"barrier":"toll_booth"},"name":"Toll Booth"},"barrier/wall":{"icon":"prison","geometry":["line","area"],"tags":{"barrier":"wall"},"name":"Wall"},"boundary/administrative":{"name":"Administrative Boundary","geometry":["line"],"tags":{"boundary":"administrative"},"fields":["admin_level"]},"building":{"icon":"building","fields":["building","levels","address"],"geometry":["point","area"],"tags":{"building":"*"},"matchScore":0.4,"terms":[],"name":"Building"},"building/bunker":{"fields":["address","levels"],"geometry":["area"],"tags":{"building":"bunker"},"matchScore":0.5,"name":"Bunker","searchable":false},"building/entrance":{"icon":"entrance","geometry":["vertex"],"tags":{"building":"entrance"},"name":"Entrance/Exit","searchable":false},"building/train_station":{"icon":"building","fields":["address","levels"],"geometry":["point","vertex","area"],"tags":{"building":"train_station"},"matchScore":0.5,"name":"Train Station","searchable":false},"building/apartments":{"icon":"commercial","fields":["address","levels"],"geometry":["area"],"tags":{"building":"apartments"},"matchScore":0.5,"name":"Apartments"},"building/barn":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"barn"},"matchScore":0.5,"name":"Barn"},"building/cabin":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"cabin"},"matchScore":0.5,"name":"Cabin"},"building/cathedral":{"icon":"place-of-worship","fields":["address","levels"],"geometry":["area"],"tags":{"building":"cathedral"},"matchScore":0.5,"name":"Cathedral Building"},"building/chapel":{"icon":"place-of-worship","fields":["address","levels"],"geometry":["area"],"tags":{"building":"chapel"},"matchScore":0.5,"name":"Chapel Building"},"building/church":{"icon":"place-of-worship","fields":["address","levels"],"geometry":["area"],"tags":{"building":"church"},"matchScore":0.5,"name":"Church Building"},"building/college":{"icon":"building","fields":["address","levels"],"geometry":["area"],"terms":["university"],"tags":{"building":"college"},"matchScore":0.5,"name":"College Building"},"building/commercial":{"icon":"commercial","fields":["address","levels","smoking"],"geometry":["area"],"tags":{"building":"commercial"},"matchScore":0.5,"name":"Commercial Building"},"building/construction":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"construction"},"matchScore":0.5,"name":"Building Under Construction"},"building/detached":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"detached"},"terms":["home","single","family","residence","dwelling"],"matchScore":0.5,"name":"Detached House"},"building/dormitory":{"icon":"building","fields":["address","levels","smoking"],"geometry":["area"],"tags":{"building":"dormitory"},"matchScore":0.5,"name":"Dormitory"},"building/garage":{"icon":"warehouse","fields":["capacity"],"geometry":["area"],"tags":{"building":"garage"},"matchScore":0.5,"name":"Garage"},"building/garages":{"icon":"warehouse","fields":["capacity"],"geometry":["area"],"tags":{"building":"garages"},"matchScore":0.5,"name":"Garages"},"building/greenhouse":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"greenhouse"},"matchScore":0.5,"name":"Greenhouse"},"building/hospital":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"hospital"},"matchScore":0.5,"name":"Hospital Building"},"building/hotel":{"icon":"building","fields":["address","levels","smoking"],"geometry":["area"],"tags":{"building":"hotel"},"matchScore":0.5,"name":"Hotel Building"},"building/house":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"house"},"terms":["home","family","residence","dwelling"],"matchScore":0.5,"name":"House"},"building/hut":{"geometry":["area"],"tags":{"building":"hut"},"matchScore":0.5,"name":"Hut"},"building/industrial":{"icon":"industrial","fields":["address","levels"],"geometry":["area"],"tags":{"building":"industrial"},"matchScore":0.5,"name":"Industrial Building"},"building/kindergarten":{"icon":"building","fields":["address","levels"],"geometry":["area"],"terms":["kindergarden","pre-school"],"tags":{"building":"kindergarten"},"matchScore":0.5,"name":"Preschool/Kindergarten Building"},"building/public":{"icon":"building","fields":["address","levels","smoking"],"geometry":["area"],"tags":{"building":"public"},"matchScore":0.5,"name":"Public Building"},"building/residential":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"residential"},"matchScore":0.5,"name":"Residential Building"},"building/retail":{"icon":"building","fields":["address","levels","smoking"],"geometry":["area"],"tags":{"building":"retail"},"matchScore":0.5,"name":"Retail Building"},"building/roof":{"icon":"building","fields":["address"],"geometry":["area"],"tags":{"building":"roof"},"matchScore":0.5,"name":"Roof"},"building/school":{"icon":"building","fields":["address","levels"],"geometry":["area"],"terms":["academy","elementary school","middle school","high school"],"tags":{"building":"school"},"matchScore":0.5,"name":"School Building"},"building/semidetached_house":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"semidetached_house"},"terms":["home","double","duplex","twin","family","residence","dwelling"],"matchScore":0.5,"name":"Semi-Detached House"},"building/shed":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"shed"},"matchScore":0.5,"name":"Shed"},"building/stable":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"stable"},"matchScore":0.5,"name":"Stable"},"building/static_caravan":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"static_caravan"},"matchScore":0.5,"name":"Static Mobile Home"},"building/terrace":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"terrace"},"terms":["home","terrace","brownstone","family","residence","dwelling"],"matchScore":0.5,"name":"Row Houses"},"building/university":{"icon":"building","fields":["address","levels"],"geometry":["area"],"terms":["college"],"tags":{"building":"university"},"matchScore":0.5,"name":"University Building"},"building/warehouse":{"icon":"warehouse","fields":["address","levels"],"geometry":["area"],"tags":{"building":"warehouse"},"matchScore":0.5,"name":"Warehouse"},"camp_site/camp_pitch":{"icon":"campsite","fields":["ref"],"geometry":["point","area"],"terms":["tent","rv"],"tags":{"camp_site":"camp_pitch"},"name":"Camp Pitch"},"craft":{"icon":"marker-stroked","fields":["craft","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"*"},"terms":[],"name":"Craft"},"craft/jeweler":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"jeweler"},"name":"Jeweler","searchable":false},"craft/locksmith":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"locksmith"},"name":"Locksmith","searchable":false},"craft/optician":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"optician"},"name":"Optician","searchable":false},"craft/tailor":{"icon":"clothing-store","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["clothes","suit"],"tags":{"craft":"tailor"},"name":"Tailor","searchable":false},"craft/basket_maker":{"icon":"art-gallery","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"basket_maker"},"name":"Basket Maker"},"craft/beekeeper":{"icon":"farm","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"beekeeper"},"name":"Beekeeper"},"craft/blacksmith":{"icon":"farm","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"blacksmith"},"name":"Blacksmith"},"craft/boatbuilder":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"boatbuilder"},"name":"Boat Builder"},"craft/bookbinder":{"icon":"library","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["book repair"],"tags":{"craft":"bookbinder"},"name":"Bookbinder"},"craft/brewery":{"icon":"beer","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["beer","bier"],"tags":{"craft":"brewery"},"name":"Brewery"},"craft/carpenter":{"icon":"logging","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["woodworker"],"tags":{"craft":"carpenter"},"name":"Carpenter"},"craft/carpet_layer":{"icon":"square","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"carpet_layer"},"name":"Carpet Layer"},"craft/caterer":{"icon":"bakery","fields":["cuisine","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"caterer"},"name":"Caterer"},"craft/clockmaker":{"fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"clockmaker"},"name":"Clockmaker"},"craft/confectionery":{"icon":"bakery","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["sweets","candy"],"tags":{"craft":"confectionery"},"name":"Confectionery"},"craft/dressmaker":{"icon":"clothing-store","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["seamstress"],"tags":{"craft":"dressmaker"},"name":"Dressmaker"},"craft/electrician":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["power","wire"],"tags":{"craft":"electrician"},"name":"Electrician"},"craft/gardener":{"icon":"garden","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["landscaper","grounds keeper"],"tags":{"craft":"gardener"},"name":"Gardener"},"craft/glaziery":{"icon":"fire-station","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["glass","stained-glass","window"],"tags":{"craft":"glaziery"},"name":"Glaziery"},"craft/handicraft":{"icon":"art-gallery","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"handicraft"},"name":"Handicraft"},"craft/hvac":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["heat*","vent*","air conditioning"],"tags":{"craft":"hvac"},"name":"HVAC"},"craft/insulator":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"insulation"},"name":"Insulator"},"craft/key_cutter":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"key_cutter"},"name":"Key Cutter"},"craft/metal_construction":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"metal_construction"},"name":"Metal Construction"},"craft/painter":{"icon":"art-gallery","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"painter"},"name":"Painter"},"craft/photographer":{"icon":"camera","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"photographer"},"name":"Photographer"},"craft/photographic_laboratory":{"icon":"camera","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["film"],"tags":{"craft":"photographic_laboratory"},"name":"Photographic Laboratory"},"craft/plasterer":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"plasterer"},"name":"Plasterer"},"craft/plumber":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["pipe"],"tags":{"craft":"plumber"},"name":"Plumber"},"craft/pottery":{"icon":"art-gallery","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["ceramic"],"tags":{"craft":"pottery"},"name":"Pottery"},"craft/rigger":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"rigger"},"name":"Rigger"},"craft/roofer":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"roofer"},"name":"Roofer"},"craft/saddler":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"saddler"},"name":"Saddler"},"craft/sailmaker":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"sailmaker"},"name":"Sailmaker"},"craft/sawmill":{"icon":"park","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["lumber"],"tags":{"craft":"sawmill"},"name":"Sawmill"},"craft/scaffolder":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"scaffolder"},"name":"Scaffolder"},"craft/sculpter":{"icon":"art-gallery","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"sculpter"},"name":"Sculpter"},"craft/shoemaker":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["cobbler"],"tags":{"craft":"shoemaker"},"name":"Shoemaker"},"craft/stonemason":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["masonry"],"tags":{"craft":"stonemason"},"name":"Stonemason"},"craft/sweep":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"sweep"},"name":"Chimney Sweep"},"craft/tiler":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"tiler"},"name":"Tiler"},"craft/tinsmith":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"tinsmith"},"name":"Tinsmith"},"craft/upholsterer":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"upholsterer"},"name":"Upholsterer"},"craft/watchmaker":{"fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"watchmaker"},"name":"Watchmaker"},"craft/window_construction":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["glass"],"tags":{"craft":"window_construction"},"name":"Window Construction"},"craft/winery":{"icon":"alcohol-shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"winery"},"name":"Winery"},"embankment":{"geometry":["line"],"tags":{"embankment":"yes"},"name":"Embankment","matchScore":0.2},"emergency/designated":{"fields":[],"geometry":["line"],"tags":{"emergency":"designated"},"terms":[],"name":"Emergency Access Designated","searchable":false,"matchScore":0.01},"emergency/destination":{"fields":[],"geometry":["line"],"tags":{"emergency":"destination"},"terms":[],"name":"Emergency Access Destination","searchable":false,"matchScore":0.01},"emergency/no":{"fields":[],"geometry":["line"],"tags":{"emergency":"no"},"terms":[],"name":"Emergency Access No","searchable":false,"matchScore":0.01},"emergency/official":{"fields":[],"geometry":["line"],"tags":{"emergency":"official"},"terms":[],"name":"Emergency Access Official","searchable":false,"matchScore":0.01},"emergency/private":{"fields":[],"geometry":["line"],"tags":{"emergency":"private"},"terms":[],"name":"Emergency Access Private","searchable":false,"matchScore":0.01},"emergency/yes":{"fields":[],"geometry":["line"],"tags":{"emergency":"yes"},"terms":[],"name":"Emergency Access Yes","searchable":false,"matchScore":0.01},"emergency/ambulance_station":{"icon":"hospital","fields":["operator","building_area","address"],"geometry":["point","area"],"terms":["EMS","EMT","rescue"],"tags":{"emergency":"ambulance_station"},"name":"Ambulance Station"},"emergency/defibrillator":{"fields":["access","opening_hours","indoor","phone"],"geometry":["point"],"terms":["AED"],"tags":{"emergency":"defibrillator"},"name":"Defibrillator"},"emergency/fire_hydrant":{"icon":"fire-station","fields":["fire_hydrant/type"],"geometry":["point","vertex"],"tags":{"emergency":"fire_hydrant"},"name":"Fire Hydrant"},"emergency/phone":{"icon":"emergency-telephone","fields":["operator"],"geometry":["point","vertex"],"tags":{"emergency":"phone"},"name":"Emergency Phone"},"entrance":{"icon":"entrance","geometry":["vertex"],"tags":{"entrance":"*"},"fields":["entrance","access_simple","address"],"name":"Entrance/Exit"},"footway/crossing":{"fields":["crossing","access","surface","kerb","tactile_paving"],"geometry":["line"],"tags":{"highway":"footway","footway":"crossing"},"terms":[],"name":"Street Crossing"},"footway/crosswalk":{"icon":"highway-footway","fields":["crossing","access","surface","kerb","tactile_paving"],"geometry":["line"],"tags":{"highway":"footway","footway":"crossing","crossing":"zebra"},"terms":["zebra crossing"],"name":"Pedestrian Crosswalk"},"footway/sidewalk":{"icon":"highway-footway","fields":["surface","lit","width","structure","access"],"geometry":["line"],"tags":{"highway":"footway","footway":"sidewalk"},"terms":[],"name":"Sidewalk"},"ford":{"geometry":["vertex"],"tags":{"ford":"yes"},"name":"Ford"},"golf/bunker":{"icon":"golf","geometry":["area"],"tags":{"golf":"bunker","natural":"sand"},"terms":["hazard","bunker"],"name":"Sand Trap"},"golf/fairway":{"icon":"golf","geometry":["area"],"tags":{"golf":"fairway","landuse":"grass"},"name":"Fairway"},"golf/green":{"icon":"golf","geometry":["area"],"tags":{"golf":"green","landuse":"grass","leisure":"pitch","sport":"golf"},"name":"Putting Green"},"golf/hole":{"icon":"golf","fields":["golf_hole","par","handicap"],"geometry":["line"],"tags":{"golf":"hole"},"name":"Golf Hole"},"golf/lateral_water_hazard_area":{"icon":"golf","geometry":["area"],"tags":{"golf":"lateral_water_hazard","natural":"water"},"name":"Lateral Water Hazard"},"golf/lateral_water_hazard_line":{"icon":"golf","geometry":["line"],"tags":{"golf":"lateral_water_hazard"},"name":"Lateral Water Hazard"},"golf/rough":{"icon":"golf","geometry":["area"],"tags":{"golf":"rough","landuse":"grass"},"name":"Rough"},"golf/tee":{"icon":"golf","geometry":["area"],"tags":{"golf":"tee","landuse":"grass"},"terms":["teeing ground"],"name":"Tee Box"},"golf/water_hazard_area":{"icon":"golf","geometry":["area"],"tags":{"golf":"water_hazard","natural":"water"},"name":"Water Hazard"},"golf/water_hazard_line":{"icon":"golf","geometry":["line"],"tags":{"golf":"water_hazard"},"name":"Water Hazard"},"healthcare/blood_donation":{"icon":"hospital","fields":["operator","address","blood_components","opening_hours","ref"],"geometry":["point","area"],"terms":["blood bank","blood donation","blood transfusion","apheresis","plasmapheresis","plateletpheresis","stem cell donation"],"tags":{"healthcare":"blood_donation"},"name":"Blood Donor Center"},"highway/bridleway":{"fields":["surface","width","structure","access"],"icon":"highway-bridleway","geometry":["line"],"tags":{"highway":"bridleway"},"terms":["bridleway","equestrian","horse"],"name":"Bridle Path"},"highway/bus_stop":{"icon":"bus","fields":["network","operator","bench","shelter","covered"],"geometry":["point","vertex"],"tags":{"highway":"bus_stop"},"terms":[],"name":"Bus Stop"},"highway/corridor":{"icon":"highway-footway","fields":["width","level","access_simple"],"geometry":["line"],"tags":{"highway":"corridor"},"terms":["gallery","hall","hallway","indoor","passage","passageway"],"name":"Indoor Corridor"},"highway/crossing":{"fields":["crossing","kerb","tactile_paving"],"geometry":["vertex"],"tags":{"highway":"crossing"},"terms":[],"name":"Street Crossing"},"highway/crosswalk":{"fields":["crossing","kerb","tactile_paving"],"geometry":["vertex"],"tags":{"highway":"crossing","crossing":"zebra"},"terms":["zebra crossing"],"name":"Pedestrian Crosswalk"},"highway/cycleway":{"icon":"highway-cycleway","fields":["surface","lit","width","oneway","structure","access"],"geometry":["line"],"tags":{"highway":"cycleway"},"terms":["bike"],"name":"Cycle Path"},"highway/footway":{"icon":"highway-footway","fields":["surface","lit","width","structure","access"],"geometry":["line","area"],"terms":["hike","hiking","trackway","trail","walk"],"tags":{"highway":"footway"},"name":"Foot Path"},"highway/give_way":{"fields":["parallel_direction"],"geometry":["vertex"],"tags":{"highway":"give_way"},"terms":["give way","yield","sign"],"name":"Yield Sign"},"highway/living_street":{"icon":"highway-living-street","fields":["oneway","maxspeed","structure","access","surface","cycleway"],"geometry":["line"],"tags":{"highway":"living_street"},"name":"Living Street"},"highway/mini_roundabout":{"icon":"circle-stroked","geometry":["vertex"],"tags":{"highway":"mini_roundabout"},"fields":["clock_direction"],"name":"Mini-Roundabout"},"highway/motorway_junction":{"geometry":["vertex"],"tags":{"highway":"motorway_junction"},"fields":["ref"],"name":"Motorway Junction / Exit"},"highway/motorway_link":{"icon":"highway-motorway-link","fields":["oneway_yes","maxspeed","structure","access","surface","ref"],"geometry":["line"],"tags":{"highway":"motorway_link"},"addTags":{"highway":"motorway_link","oneway":"yes"},"removeTags":{"highway":"motorway_link","oneway":"yes"},"terms":["ramp","on ramp","off ramp"],"name":"Motorway Link"},"highway/motorway":{"icon":"highway-motorway","fields":["oneway_yes","maxspeed","structure","access","lanes","surface","ref"],"geometry":["line"],"tags":{"highway":"motorway"},"terms":[],"name":"Motorway"},"highway/path":{"icon":"highway-path","fields":["surface","width","structure","access","incline","sac_scale","trail_visibility","mtb/scale","mtb/scale/uphill","mtb/scale/imba","ref"],"geometry":["line"],"terms":["hike","hiking","trackway","trail","walk"],"tags":{"highway":"path"},"name":"Path"},"highway/pedestrian":{"icon":"highway-footway","fields":["surface","lit","width","oneway","structure","access"],"geometry":["line","area"],"tags":{"highway":"pedestrian"},"terms":[],"name":"Pedestrian Street"},"highway/primary_link":{"icon":"highway-primary-link","fields":["oneway","maxspeed","structure","access","surface","ref","cycleway"],"geometry":["line"],"tags":{"highway":"primary_link"},"terms":["ramp","on ramp","off ramp"],"name":"Primary Link"},"highway/primary":{"icon":"highway-primary","fields":["oneway","maxspeed","structure","access","lanes","surface","ref","cycleway"],"geometry":["line"],"tags":{"highway":"primary"},"terms":[],"name":"Primary Road"},"highway/raceway":{"icon":"highway-unclassified","fields":["oneway","surface","sport_racing","structure"],"geometry":["line"],"tags":{"highway":"raceway"},"addTags":{"highway":"raceway","sport":"motor"},"terms":["auto*","race*","nascar"],"name":"Motor Raceway"},"highway/residential":{"icon":"highway-residential","fields":["oneway","maxspeed","structure","access","surface","cycleway"],"geometry":["line"],"tags":{"highway":"residential"},"terms":[],"name":"Residential Road"},"highway/rest_area":{"geometry":["point","vertex","area"],"tags":{"highway":"rest_area"},"terms":["rest stop"],"name":"Rest Area"},"highway/road":{"icon":"highway-road","fields":["oneway","maxspeed","structure","access","surface"],"geometry":["line"],"tags":{"highway":"road"},"terms":[],"name":"Unknown Road"},"highway/secondary_link":{"icon":"highway-secondary-link","fields":["oneway","maxspeed","structure","access","surface","ref","cycleway"],"geometry":["line"],"tags":{"highway":"secondary_link"},"terms":["ramp","on ramp","off ramp"],"name":"Secondary Link"},"highway/secondary":{"icon":"highway-secondary","fields":["oneway","maxspeed","structure","access","lanes","surface","ref","cycleway"],"geometry":["line"],"tags":{"highway":"secondary"},"terms":[],"name":"Secondary Road"},"highway/service":{"icon":"highway-service","fields":["service","oneway","maxspeed","structure","access","surface","cycleway"],"geometry":["line"],"tags":{"highway":"service"},"terms":[],"name":"Service Road"},"highway/service/alley":{"icon":"highway-service","fields":["oneway","access","surface"],"geometry":["line"],"tags":{"highway":"service","service":"alley"},"name":"Alley"},"highway/service/drive-through":{"icon":"highway-service","fields":["oneway","access","surface"],"geometry":["line"],"tags":{"highway":"service","service":"drive-through"},"name":"Drive-Through"},"highway/service/driveway":{"icon":"highway-service","fields":["oneway","access","surface"],"geometry":["line"],"tags":{"highway":"service","service":"driveway"},"name":"Driveway"},"highway/service/emergency_access":{"icon":"highway-service","fields":["oneway","access","surface"],"geometry":["line"],"tags":{"highway":"service","service":"emergency_access"},"name":"Emergency Access"},"highway/service/parking_aisle":{"icon":"highway-service","fields":["oneway","access","surface"],"geometry":["line"],"tags":{"highway":"service","service":"parking_aisle"},"name":"Parking Aisle"},"highway/services":{"geometry":["point","vertex","area"],"tags":{"highway":"services"},"terms":["services","travel plaza","service station"],"name":"Service Area"},"highway/steps":{"fields":["surface","lit","width","incline_steps","handrail"],"icon":"highway-steps","geometry":["line"],"tags":{"highway":"steps"},"terms":["stairs","staircase"],"name":"Steps"},"highway/stop":{"fields":["stop","parallel_direction"],"geometry":["vertex"],"tags":{"highway":"stop"},"terms":["stop","halt","sign"],"name":"Stop Sign"},"highway/street_lamp":{"geometry":["point","vertex"],"tags":{"highway":"street_lamp"},"fields":["lamp_type","ref"],"terms":["streetlight","street light","lamp","light","gaslight"],"name":"Street Lamp"},"highway/tertiary_link":{"icon":"highway-tertiary-link","fields":["oneway","maxspeed","structure","access","surface","ref","cycleway"],"geometry":["line"],"tags":{"highway":"tertiary_link"},"terms":["ramp","on ramp","off ramp"],"name":"Tertiary Link"},"highway/tertiary":{"icon":"highway-tertiary","fields":["oneway","maxspeed","structure","access","lanes","surface","ref","cycleway"],"geometry":["line"],"tags":{"highway":"tertiary"},"terms":[],"name":"Tertiary Road"},"highway/track":{"icon":"highway-track","fields":["surface","width","structure","access","incline","tracktype","smoothness","mtb/scale","mtb/scale/uphill","mtb/scale/imba"],"geometry":["line"],"tags":{"highway":"track"},"terms":["woods road","forest road","logging road","fire road","farm road","agricultural road","ranch road","carriage road","primitive","unmaintained","rut","offroad","4wd","4x4","four wheel drive","atv","quad","jeep","double track","two track"],"name":"Unmaintained Track Road"},"highway/traffic_signals":{"geometry":["vertex"],"tags":{"highway":"traffic_signals"},"fields":["traffic_signals"],"terms":["light","stoplight","traffic light"],"name":"Traffic Signals"},"highway/trunk_link":{"icon":"highway-trunk-link","fields":["oneway","maxspeed","structure","access","surface","ref"],"geometry":["line"],"tags":{"highway":"trunk_link"},"terms":["ramp","on ramp","off ramp"],"name":"Trunk Link"},"highway/trunk":{"icon":"highway-trunk","fields":["oneway","maxspeed","structure","access","lanes","surface","ref"],"geometry":["line"],"tags":{"highway":"trunk"},"terms":[],"name":"Trunk Road"},"highway/turning_circle":{"icon":"circle-stroked","geometry":["vertex"],"tags":{"highway":"turning_circle"},"terms":["cul-de-sac"],"name":"Turning Circle"},"highway/turning_loop":{"icon":"circle","geometry":["vertex"],"tags":{"highway":"turning_loop"},"terms":["cul-de-sac"],"name":"Turning Loop (Island)"},"highway/unclassified":{"icon":"highway-unclassified","fields":["oneway","maxspeed","structure","access","surface","cycleway"],"geometry":["line"],"tags":{"highway":"unclassified"},"terms":[],"name":"Minor/Unclassified Road"},"historic":{"fields":["historic"],"geometry":["point","vertex","area"],"tags":{"historic":"*"},"name":"Historic Site"},"historic/archaeological_site":{"geometry":["point","vertex","area"],"tags":{"historic":"archaeological_site"},"name":"Archaeological Site"},"historic/boundary_stone":{"geometry":["point","vertex"],"tags":{"historic":"boundary_stone"},"name":"Boundary Stone"},"historic/castle":{"geometry":["point","area"],"tags":{"historic":"castle"},"name":"Castle"},"historic/memorial":{"icon":"monument","geometry":["point","vertex","area"],"tags":{"historic":"memorial"},"name":"Memorial"},"historic/monument":{"icon":"monument","geometry":["point","vertex","area"],"tags":{"historic":"monument"},"name":"Monument"},"historic/ruins":{"geometry":["point","vertex","area"],"tags":{"historic":"ruins"},"name":"Ruins"},"historic/wayside_cross":{"icon":"religious-christian","geometry":["point","vertex","area"],"tags":{"historic":"wayside_cross"},"name":"Wayside Cross"},"historic/wayside_shrine":{"geometry":["point","vertex","area"],"tags":{"historic":"wayside_shrine"},"name":"Wayside Shrine"},"junction":{"geometry":["vertex","area"],"tags":{"junction":"yes"},"name":"Junction"},"landuse":{"fields":["landuse"],"geometry":["area"],"tags":{"landuse":"*"},"name":"Land Use"},"landuse/farm":{"icon":"farm","fields":["crop"],"geometry":["point","area"],"tags":{"landuse":"farm"},"terms":[],"name":"Farmland","searchable":false},"landuse/allotments":{"geometry":["area"],"tags":{"landuse":"allotments"},"terms":["allotment","garden"],"name":"Community Garden"},"landuse/basin":{"geometry":["area"],"tags":{"landuse":"basin"},"terms":[],"name":"Basin"},"landuse/cemetery":{"icon":"cemetery","fields":["religion","denomination"],"geometry":["area"],"tags":{"landuse":"cemetery"},"terms":[],"name":"Cemetery"},"landuse/churchyard":{"fields":["religion","denomination"],"geometry":["area"],"tags":{"landuse":"churchyard"},"terms":[],"name":"Churchyard"},"landuse/commercial":{"icon":"commercial","geometry":["area"],"tags":{"landuse":"commercial"},"terms":[],"name":"Commercial Area"},"landuse/construction":{"fields":["construction","operator"],"geometry":["area"],"tags":{"landuse":"construction"},"terms":[],"name":"Construction"},"landuse/farmland":{"icon":"farm","fields":["crop"],"geometry":["area"],"tags":{"landuse":"farmland"},"terms":[],"name":"Farmland"},"landuse/farmyard":{"icon":"farm","fields":["crop"],"geometry":["area"],"tags":{"landuse":"farmyard"},"terms":[],"name":"Farmyard"},"landuse/forest":{"icon":"park2","fields":["leaf_type","leaf_cycle"],"geometry":["area"],"tags":{"landuse":"forest"},"terms":["tree"],"name":"Forest"},"landuse/garages":{"geometry":["area"],"tags":{"landuse":"garages"},"terms":[],"name":"Garages"},"landuse/grass":{"geometry":["area"],"tags":{"landuse":"grass"},"terms":[],"name":"Grass"},"landuse/industrial":{"icon":"industrial","geometry":["area"],"tags":{"landuse":"industrial"},"terms":[],"name":"Industrial Area"},"landuse/landfill":{"geometry":["area"],"tags":{"landuse":"landfill"},"terms":["dump"],"name":"Landfill"},"landuse/meadow":{"geometry":["area"],"tags":{"landuse":"meadow"},"terms":[],"name":"Meadow"},"landuse/military":{"geometry":["area"],"tags":{"landuse":"military"},"terms":[],"name":"Military Area"},"landuse/orchard":{"icon":"park2","fields":["trees"],"geometry":["area"],"tags":{"landuse":"orchard"},"terms":[],"name":"Orchard"},"landuse/plant_nursery":{"icon":"garden","fields":["name"],"geometry":["point","area"],"tags":{"landuse":"plant_nursery"},"terms":["vivero"],"name":"Plant Nursery"},"landuse/quarry":{"geometry":["area"],"tags":{"landuse":"quarry"},"terms":[],"name":"Quarry"},"landuse/recreation_ground":{"geometry":["area"],"tags":{"landuse":"recreation_ground"},"terms":["playing fields"],"name":"Recreation Ground"},"landuse/residential":{"icon":"building","geometry":["area"],"tags":{"landuse":"residential"},"terms":[],"name":"Residential Area"},"landuse/retail":{"icon":"shop","geometry":["area"],"tags":{"landuse":"retail"},"name":"Retail Area"},"landuse/vineyard":{"geometry":["area"],"tags":{"landuse":"vineyard"},"terms":[],"name":"Vineyard"},"leisure":{"fields":["leisure"],"geometry":["point","vertex","area"],"tags":{"leisure":"*"},"name":"Leisure"},"leisure/adult_gaming_centre":{"fields":["operator","address","building_area","opening_hours","smoking"],"geometry":["point","area"],"terms":["gambling","slot machine"],"tags":{"leisure":"adult_gaming_centre"},"name":"Adult Gaming Center"},"leisure/bird_hide":{"fields":["building_area"],"geometry":["point","area"],"tags":{"leisure":"bird_hide"},"terms":["machan","ornithology"],"name":"Bird Hide"},"leisure/bowling_alley":{"fields":["operator","address","building_area","opening_hours","smoking"],"geometry":["point","area"],"terms":[],"tags":{"leisure":"bowling_alley"},"name":"Bowling Alley"},"leisure/common":{"geometry":["point","area"],"terms":["open space"],"tags":{"leisure":"common"},"name":"Common"},"leisure/dog_park":{"icon":"dog-park","geometry":["point","area"],"terms":[],"tags":{"leisure":"dog_park"},"name":"Dog Park"},"leisure/firepit":{"geometry":["point","area"],"tags":{"leisure":"firepit"},"terms":["fireplace","campfire"],"name":"Firepit"},"leisure/fitness_centre":{"icon":"pitch","fields":["sport","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_centre"},"terms":["health","gym","leisure","studio"],"name":"Gym / Fitness Center"},"leisure/fitness_centre/yoga":{"icon":"pitch","fields":["sport","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["studio"],"tags":{"leisure":"fitness_centre","sport":"yoga"},"name":"Yoga Studio"},"leisure/fitness_station":{"icon":"pitch","fields":["sport","address","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station"},"terms":["fitness","gym"],"name":"Outdoor Fitness Station"},"leisure/garden":{"icon":"garden","fields":["access_simple"],"geometry":["point","vertex","area"],"tags":{"leisure":"garden"},"name":"Garden"},"leisure/golf_course":{"icon":"golf","fields":["operator","address","opening_hours"],"geometry":["point","area"],"terms":["links"],"tags":{"leisure":"golf_course"},"name":"Golf Course"},"leisure/ice_rink":{"icon":"pitch","fields":["seasonal","sport_ice","operator","address","building","opening_hours"],"geometry":["point","area"],"terms":["hockey","skating","curling"],"tags":{"leisure":"ice_rink"},"name":"Ice Rink"},"leisure/marina":{"icon":"harbor","fields":["operator","address","capacity","fee","sanitary_dump_station","power_supply","internet_access"],"geometry":["point","vertex","area"],"terms":["boat"],"tags":{"leisure":"marina"},"name":"Marina"},"leisure/miniature_golf":{"icon":"golf","fields":["operator","address","opening_hours"],"geometry":["point","area"],"terms":["crazy golf","mini golf","putt-putt"],"tags":{"leisure":"miniature_golf"},"name":"Miniature Golf"},"leisure/nature_reserve":{"icon":"park","geometry":["point","area"],"tags":{"leisure":"nature_reserve"},"terms":["protected","wildlife"],"name":"Nature Reserve"},"leisure/park":{"icon":"park","geometry":["point","area"],"terms":["esplanade","estate","forest","garden","grass","green","grounds","lawn","lot","meadow","parkland","place","playground","plaza","pleasure garden","recreation area","square","tract","village green","woodland"],"tags":{"leisure":"park"},"name":"Park"},"leisure/picnic_table":{"geometry":["point"],"tags":{"leisure":"picnic_table"},"terms":["bench"],"name":"Picnic Table"},"leisure/pitch":{"icon":"pitch","fields":["sport","surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch"},"terms":["field"],"name":"Sport Pitch"},"leisure/pitch/american_football":{"icon":"america-football","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"american_football"},"terms":[],"name":"American Football Field"},"leisure/pitch/baseball":{"icon":"baseball","fields":["lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"baseball"},"terms":[],"name":"Baseball Diamond"},"leisure/pitch/basketball":{"icon":"basketball","fields":["surface","hoops","lit","access_simple"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"basketball"},"terms":[],"name":"Basketball Court"},"leisure/pitch/bowls":{"icon":"pitch","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"bowls"},"terms":[],"name":"Bowling Green"},"leisure/pitch/rugby_league":{"icon":"america-football","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"rugby_league"},"terms":[],"name":"Rugby League Field"},"leisure/pitch/rugby_union":{"icon":"america-football","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"rugby_union"},"terms":[],"name":"Rugby Union Field"},"leisure/pitch/skateboard":{"icon":"pitch","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"skateboard"},"terms":[],"name":"Skate Park"},"leisure/pitch/soccer":{"icon":"soccer","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"soccer"},"terms":[],"name":"Soccer Field"},"leisure/pitch/tennis":{"icon":"tennis","fields":["surface","lit","access_simple"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"tennis"},"terms":[],"name":"Tennis Court"},"leisure/pitch/volleyball":{"icon":"pitch","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"volleyball"},"terms":[],"name":"Volleyball Court"},"leisure/playground":{"icon":"playground","geometry":["point","area"],"terms":["jungle gym","play area"],"tags":{"leisure":"playground"},"name":"Playground"},"leisure/running_track":{"icon":"pitch","fields":["surface","sport_racing","lit","width","lanes"],"geometry":["point","line"],"tags":{"leisure":"track","sport":"running"},"name":"Running Track"},"leisure/slipway":{"geometry":["point","line"],"terms":["boat launch","boat ramp"],"tags":{"leisure":"slipway"},"name":"Slipway"},"leisure/sports_centre":{"icon":"pitch","fields":["sport","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"sports_centre"},"terms":[],"name":"Sports Center / Complex"},"leisure/sports_centre/swimming":{"icon":"swimming","fields":["access_simple","operator","address","building"],"geometry":["point","area"],"terms":["dive","water"],"tags":{"leisure":"sports_centre","sport":"swimming"},"name":"Swimming Pool Facility"},"leisure/stadium":{"icon":"pitch","fields":["sport","address"],"geometry":["point","area"],"tags":{"leisure":"stadium"},"name":"Stadium"},"leisure/swimming_pool":{"icon":"swimming","fields":["access_simple","operator","address"],"geometry":["point","area"],"terms":["dive","water"],"tags":{"leisure":"swimming_pool"},"name":"Swimming Pool"},"leisure/track":{"icon":"highway-road","fields":["surface","sport_racing","lit","width","lanes"],"geometry":["point","line"],"tags":{"leisure":"track"},"name":"Racetrack (non-Motorsport)"},"leisure/water_park":{"icon":"swimming","fields":["operator","address"],"geometry":["point","area"],"terms":["swim","pool","dive"],"tags":{"leisure":"water_park"},"name":"Water Park"},"line":{"name":"Line","tags":{},"geometry":["line"],"matchScore":0.1},"man_made":{"fields":["man_made"],"geometry":["point","vertex","line","area"],"tags":{"man_made":"*"},"name":"Man Made"},"man_made/embankment":{"geometry":["line"],"tags":{"man_made":"embankment"},"name":"Embankment","searchable":false},"man_made/adit":{"geometry":["point","area"],"fields":["operator"],"terms":["entrance","underground","mine","cave"],"tags":{"man_made":"adit"},"name":"Adit"},"man_made/breakwater":{"geometry":["line","area"],"tags":{"man_made":"breakwater"},"name":"Breakwater"},"man_made/bridge":{"geometry":["area"],"tags":{"man_made":"bridge"},"name":"Bridge"},"man_made/chimney":{"geometry":["point","area"],"tags":{"man_made":"chimney"},"name":"Chimney"},"man_made/cutline":{"geometry":["line"],"tags":{"man_made":"cutline"},"name":"Cut line"},"man_made/flagpole":{"geometry":["point"],"tags":{"man_made":"flagpole"},"name":"Flagpole","icon":"embassy"},"man_made/gasometer":{"geometry":["point","area"],"terms":["gas holder"],"tags":{"man_made":"gasometer"},"name":"Gasometer"},"man_made/groyne":{"geometry":["line","area"],"tags":{"man_made":"groyne"},"name":"Groyne"},"man_made/lighthouse":{"icon":"lighthouse","fields":["building_area"],"geometry":["point","area"],"tags":{"man_made":"lighthouse"},"name":"Lighthouse"},"man_made/mast":{"fields":["tower/type","tower/construction","height"],"geometry":["point"],"terms":["broadcast tower","cell phone tower","cell tower","guyed tower","mobile phone tower","radio tower","television tower","transmission mast","transmission tower","tv tower"],"tags":{"man_made":"mast"},"name":"Radio Mast"},"man_made/observation":{"geometry":["point","area"],"terms":["lookout tower","fire tower"],"tags":{"man_made":"tower","tower:type":"observation"},"name":"Observation Tower"},"man_made/petroleum_well":{"geometry":["point"],"terms":["drilling rig","oil derrick","oil drill","oil horse","oil rig","oil pump","petroleum well","pumpjack"],"tags":{"man_made":"petroleum_well"},"name":"Oil Well"},"man_made/pier":{"geometry":["line","area"],"terms":["dock"],"tags":{"man_made":"pier"},"name":"Pier"},"man_made/pipeline":{"icon":"pipeline-line","fields":["location","operator"],"geometry":["line"],"tags":{"man_made":"pipeline"},"name":"Pipeline"},"man_made/pumping_station":{"geometry":["point","area"],"tags":{"man_made":"pumping_station"},"name":"Pumping Station"},"man_made/silo":{"fields":["building_area","crop"],"geometry":["point","area"],"terms":["grain","corn","wheat"],"tags":{"man_made":"silo"},"name":"Silo"},"man_made/storage_tank":{"fields":["building_area","content"],"geometry":["point","area"],"terms":["water","oil","gas","petrol"],"tags":{"man_made":"storage_tank"},"name":"Storage Tank"},"man_made/surveillance":{"icon":"camera","geometry":["point"],"terms":["cctv"],"tags":{"man_made":"surveillance"},"name":"Surveillance"},"man_made/survey_point":{"icon":"monument","fields":["ref"],"geometry":["point","vertex"],"tags":{"man_made":"survey_point"},"name":"Survey Point"},"man_made/tower":{"fields":["tower/type","tower/construction","height"],"geometry":["point","area"],"tags":{"man_made":"tower"},"name":"Tower"},"man_made/wastewater_plant":{"icon":"water","fields":["operator","address"],"geometry":["point","area"],"terms":["sewage*","water treatment plant","reclamation plant"],"tags":{"man_made":"wastewater_plant"},"name":"Wastewater Plant"},"man_made/water_tower":{"icon":"water","fields":["operator"],"geometry":["point","area"],"tags":{"man_made":"water_tower"},"name":"Water Tower"},"man_made/water_well":{"fields":["operator"],"geometry":["point","area"],"tags":{"man_made":"water_well"},"name":"Water Well"},"man_made/water_works":{"icon":"water","fields":["operator","address"],"geometry":["point","area"],"tags":{"man_made":"water_works"},"name":"Water Works"},"man_made/works":{"geometry":["point","area"],"terms":["car assembly plant","aluminium processing plant","brewery","furniture manufacture factory","oil refinery","plastic recycling"],"tags":{"man_made":"works"},"name":"Works"},"military/airfield":{"icon":"airfield","geometry":["point","vertex","area"],"terms":[],"tags":{"military":"airfield"},"name":"Airfield"},"military/barracks":{"geometry":["point","vertex","area"],"terms":[],"tags":{"military":"barracks"},"name":"Barracks"},"military/bunker":{"geometry":["point","vertex","area"],"terms":[],"tags":{"military":"bunker"},"name":"Bunker"},"military/checkpoint":{"geometry":["point","vertex","area"],"terms":[],"tags":{"military":"checkpoint"},"name":"Checkpoint"},"military/danger_area":{"geometry":["point","vertex","area"],"terms":[],"tags":{"military":"danger_area"},"name":"Danger Area"},"military/naval_base":{"geometry":["point","vertex","area"],"terms":[],"tags":{"military":"naval_base"},"name":"Naval Base"},"military/obstacle_course":{"geometry":["point","vertex","area"],"terms":[],"tags":{"military":"obstacle_course"},"name":"Obstacle Course"},"military/range":{"geometry":["point","vertex","area"],"terms":[],"tags":{"military":"range"},"name":"Military Range"},"military/training_area":{"geometry":["point","vertex","area"],"terms":[],"tags":{"military":"training_area"},"name":"Training area"},"natural":{"fields":["natural"],"geometry":["point","vertex","area"],"tags":{"natural":"*"},"name":"Natural"},"natural/bay":{"geometry":["point","area"],"terms":[],"tags":{"natural":"bay"},"name":"Bay"},"natural/beach":{"fields":["surface"],"geometry":["point","area"],"terms":[],"tags":{"natural":"beach"},"name":"Beach"},"natural/cave_entrance":{"geometry":["point","area"],"fields":["fee","access_simple"],"terms":["cavern","hollow","grotto","shelter","cavity"],"tags":{"natural":"cave_entrance"},"name":"Cave Entrance"},"natural/cliff":{"geometry":["point","vertex","line","area"],"terms":[],"tags":{"natural":"cliff"},"name":"Cliff"},"natural/coastline":{"geometry":["line"],"terms":["shore"],"tags":{"natural":"coastline"},"name":"Coastline"},"natural/fell":{"geometry":["area"],"terms":[],"tags":{"natural":"fell"},"name":"Fell"},"natural/glacier":{"geometry":["area"],"terms":[],"tags":{"natural":"glacier"},"name":"Glacier"},"natural/grassland":{"geometry":["point","area"],"terms":[],"tags":{"natural":"grassland"},"name":"Grassland"},"natural/heath":{"geometry":["area"],"terms":[],"tags":{"natural":"heath"},"name":"Heath"},"natural/peak":{"icon":"triangle","fields":["elevation"],"geometry":["point","vertex"],"tags":{"natural":"peak"},"terms":["acme","aiguille","alp","climax","crest","crown","hill","mount","mountain","pinnacle","summit","tip","top"],"name":"Peak"},"natural/saddle":{"icon":"triangle-stroked","fields":["elevation"],"geometry":["point","vertex"],"tags":{"natural":"saddle"},"terms":["pass","mountain pass","top"],"name":"Saddle"},"natural/scree":{"geometry":["area"],"tags":{"natural":"scree"},"terms":["loose rocks"],"name":"Scree"},"natural/scrub":{"geometry":["area"],"tags":{"natural":"scrub"},"terms":["bush","shrubs"],"name":"Scrub"},"natural/spring":{"geometry":["point","vertex"],"terms":[],"tags":{"natural":"spring"},"name":"Spring"},"natural/tree_row":{"fields":["leaf_type","leaf_cycle","denotation"],"icon":"park","geometry":["line"],"terms":[],"tags":{"natural":"tree_row"},"name":"Tree row"},"natural/tree":{"fields":["leaf_type_singular","leaf_cycle_singular","denotation"],"icon":"park","geometry":["point","vertex"],"terms":[],"tags":{"natural":"tree"},"name":"Tree"},"natural/volcano":{"icon":"triangle","fields":["elevation"],"geometry":["point","vertex"],"tags":{"natural":"volcano"},"terms":["mountain","crater"],"name":"Volcano"},"natural/water":{"fields":["water"],"geometry":["area"],"tags":{"natural":"water"},"icon":"water","name":"Water"},"natural/water/lake":{"geometry":["area"],"tags":{"natural":"water","water":"lake"},"terms":["lakelet","loch","mere"],"icon":"water","name":"Lake"},"natural/water/pond":{"geometry":["area"],"tags":{"natural":"water","water":"pond"},"terms":["lakelet","millpond","tarn","pool","mere"],"icon":"water","name":"Pond"},"natural/water/reservoir":{"geometry":["area"],"tags":{"natural":"water","water":"reservoir"},"icon":"water","name":"Reservoir"},"natural/wetland":{"icon":"wetland","fields":["wetland"],"geometry":["point","area"],"tags":{"natural":"wetland"},"terms":[],"name":"Wetland"},"natural/wood":{"icon":"park2","fields":["leaf_type","leaf_cycle"],"geometry":["point","area"],"tags":{"natural":"wood"},"terms":["tree"],"name":"Wood"},"office":{"icon":"commercial","fields":["office","address","building_area","opening_hours","smoking"],"geometry":["point","vertex","area"],"tags":{"office":"*"},"terms":[],"name":"Office"},"office/travel_agent":{"icon":"suitcase","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"travel_agent"},"terms":[],"name":"Travel Agency","searchable":false},"office/accountant":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"accountant"},"terms":[],"name":"Accountant"},"office/administrative":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"administrative"},"terms":[],"name":"Administrative Office"},"office/architect":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"architect"},"terms":[],"name":"Architect"},"office/company":{"icon":"commercial","fields":["address","building_area","opening_hours","smoking"],"geometry":["point","vertex","area"],"tags":{"office":"company"},"terms":[],"name":"Company Office"},"office/educational_institution":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"educational_institution"},"terms":[],"name":"Educational Institution"},"office/employment_agency":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"employment_agency"},"terms":["job"],"name":"Employment Agency"},"office/estate_agent":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"estate_agent"},"terms":[],"name":"Real Estate Office"},"office/financial":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"financial"},"terms":[],"name":"Financial Office"},"office/government":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"government"},"terms":[],"name":"Government Office"},"office/government/register_office":{"icon":"town-hall","fields":["address","building_area","opening_hours","operator"],"geometry":["point","area"],"terms":["clerk","marriage","death","birth","certificate"],"tags":{"office":"government","government":"register_office"},"name":"Register Office"},"office/insurance":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"insurance"},"terms":[],"name":"Insurance Office"},"office/it":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"it"},"terms":[],"name":"IT Office"},"office/lawyer":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"lawyer"},"terms":[],"name":"Law Office"},"office/newspaper":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"newspaper"},"terms":[],"name":"Newspaper"},"office/ngo":{"icon":"commercial","fields":["address","building_area","opening_hours","smoking"],"geometry":["point","vertex","area"],"tags":{"office":"ngo"},"terms":[],"name":"NGO Office"},"office/physician":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"physician"},"terms":[],"name":"Physician"},"office/political_party":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"political_party"},"terms":[],"name":"Political Party"},"office/research":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"research"},"terms":[],"name":"Research Office"},"office/telecommunication":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"telecommunication"},"terms":[],"name":"Telecom Office"},"office/therapist":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"therapist"},"terms":[],"name":"Therapist"},"piste":{"icon":"skiing","fields":["piste/type","piste/difficulty","piste/grooming","oneway","lit"],"geometry":["point","line","area"],"terms":["ski","sled","sleigh","snowboard","nordic","downhill","snowmobile"],"tags":{"piste:type":"*"},"name":"Piste/Ski Trail"},"place/city":{"icon":"city","fields":["population"],"geometry":["point","area"],"tags":{"place":"city"},"name":"City"},"place/farm":{"icon":"farm","geometry":["point","area"],"tags":{"place":"farm"},"name":"Farm"},"place/hamlet":{"icon":"triangle-stroked","fields":["population"],"geometry":["point","area"],"tags":{"place":"hamlet"},"name":"Hamlet"},"place/island":{"geometry":["point","area"],"terms":["archipelago","atoll","bar","cay","isle","islet","key","reef"],"tags":{"place":"island"},"name":"Island"},"place/isolated_dwelling":{"geometry":["point","area"],"tags":{"place":"isolated_dwelling"},"name":"Isolated Dwelling"},"place/locality":{"icon":"marker","geometry":["point","area"],"tags":{"place":"locality"},"name":"Locality"},"place/neighbourhood":{"icon":"triangle-stroked","fields":["population"],"geometry":["point","area"],"tags":{"place":"neighbourhood"},"terms":["neighbourhood"],"name":"Neighborhood"},"place/suburb":{"icon":"triangle-stroked","fields":["population"],"geometry":["point","area"],"tags":{"place":"suburb"},"terms":["Boro","Quarter"],"name":"Borough"},"place/town":{"icon":"town","fields":["population"],"geometry":["point","area"],"tags":{"place":"town"},"name":"Town"},"place/village":{"icon":"village","fields":["population"],"geometry":["point","area"],"tags":{"place":"village"},"name":"Village"},"point":{"name":"Point","tags":{},"geometry":["point"],"matchScore":0.1},"power/sub_station":{"fields":["substation","operator","building"],"geometry":["point","area"],"tags":{"power":"sub_station"},"name":"Substation","searchable":false},"power/generator":{"fields":["operator","generator/source","generator/method","generator/type"],"geometry":["point","vertex","area"],"tags":{"power":"generator"},"name":"Power Generator"},"power/line":{"geometry":["line"],"tags":{"power":"line"},"name":"Power Line","icon":"power-line"},"power/minor_line":{"geometry":["line"],"tags":{"power":"minor_line"},"name":"Minor Power Line","icon":"power-line"},"power/pole":{"geometry":["vertex"],"tags":{"power":"pole"},"name":"Power Pole"},"power/substation":{"fields":["substation","operator","building"],"geometry":["point","area"],"tags":{"power":"substation"},"name":"Substation"},"power/tower":{"geometry":["vertex"],"tags":{"power":"tower"},"name":"High-Voltage Tower"},"power/transformer":{"geometry":["point","vertex","area"],"tags":{"power":"transformer"},"name":"Transformer"},"public_transport/platform":{"fields":["ref","network","operator","shelter"],"geometry":["point","vertex","line","area"],"tags":{"public_transport":"platform"},"name":"Platform"},"public_transport/stop_position":{"icon":"bus","fields":["ref","network","operator"],"geometry":["vertex"],"tags":{"public_transport":"stop_position"},"name":"Stop Position"},"railway/abandoned":{"icon":"railway-abandoned","geometry":["line"],"tags":{"railway":"abandoned"},"fields":["structure","service_rail"],"terms":[],"name":"Abandoned Railway"},"railway/crossing":{"icon":"cross","geometry":["vertex"],"tags":{"railway":"crossing"},"terms":["crossing","pedestrian crossing","railroad crossing","level crossing","grade crossing","path through railroad","train crossing"],"name":"Railway Crossing (Path)"},"railway/disused":{"icon":"railway-disused","geometry":["line"],"tags":{"railway":"disused"},"fields":["structure","service_rail"],"terms":[],"name":"Disused Railway"},"railway/funicular":{"geometry":["line"],"terms":["venicular","cliff railway","cable car","cable railway","funicular railway"],"fields":["structure","gauge","service_rail"],"tags":{"railway":"funicular"},"icon":"railway-rail","name":"Funicular"},"railway/halt":{"icon":"rail","geometry":["point","vertex"],"tags":{"railway":"halt"},"name":"Railway Halt","terms":["break","interrupt","rest","wait","interruption"]},"railway/level_crossing":{"icon":"cross","geometry":["vertex"],"tags":{"railway":"level_crossing"},"terms":["crossing","railroad crossing","level crossing","grade crossing","road through railroad","train crossing"],"name":"Railway Crossing (Road)"},"railway/monorail":{"icon":"railway-monorail","geometry":["line"],"tags":{"railway":"monorail"},"fields":["structure","electrified","service_rail"],"terms":[],"name":"Monorail"},"railway/narrow_gauge":{"icon":"railway-rail","geometry":["line"],"tags":{"railway":"narrow_gauge"},"fields":["structure","gauge","electrified","service_rail"],"terms":["narrow gauge railway","narrow gauge railroad"],"name":"Narrow Gauge Rail"},"railway/platform":{"geometry":["point","vertex","line","area"],"tags":{"railway":"platform"},"name":"Railway Platform"},"railway/rail":{"icon":"railway-rail","geometry":["line"],"tags":{"railway":"rail"},"fields":["structure","gauge","electrified","maxspeed","service_rail"],"terms":[],"name":"Rail"},"railway/station":{"icon":"rail","fields":["network","operator","address","building_area"],"geometry":["point","vertex","area"],"tags":{"railway":"station"},"terms":["train station","station"],"name":"Railway Station"},"railway/subway_entrance":{"icon":"rail-metro","geometry":["point"],"tags":{"railway":"subway_entrance"},"terms":[],"name":"Subway Entrance"},"railway/subway":{"icon":"railway-subway","geometry":["line"],"tags":{"railway":"subway"},"fields":["structure","gauge","electrified","service_rail"],"terms":[],"name":"Subway"},"railway/tram":{"icon":"railway-light-rail","geometry":["line"],"tags":{"railway":"tram"},"fields":["structure","gauge","electrified","service_rail"],"terms":["streetcar"],"name":"Tram"},"relation":{"name":"Relation","icon":"relation","tags":{},"geometry":["relation"],"fields":["relation"]},"route/ferry":{"icon":"ferry-line","geometry":["line"],"tags":{"route":"ferry"},"name":"Ferry Route"},"shop":{"icon":"shop","fields":["shop","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"*"},"terms":[],"name":"Shop"},"shop/fishmonger":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"fishmonger"},"name":"Fishmonger","searchable":false},"shop/vacant":{"icon":"shop","fields":["address","building_area"],"geometry":["point","area"],"tags":{"shop":"vacant"},"name":"Vacant Shop","searchable":false},"shop/alcohol":{"icon":"alcohol-shop","fields":["operator","address","building_area","opening_hours","drive_through"],"geometry":["point","area"],"terms":["alcohol","beer","booze","wine"],"tags":{"shop":"alcohol"},"name":"Liquor Store"},"shop/anime":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"anime"},"terms":["manga","japan","cosplay","figurine","dakimakura"],"name":"Anime Shop"},"shop/antiques":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"antiques"},"name":"Antiques Shop"},"shop/art":{"icon":"shop","fields":["artwork_type","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["art*","exhibit*","gallery"],"tags":{"shop":"art"},"name":"Art Store"},"shop/baby_goods":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"baby_goods"},"name":"Baby Goods Store"},"shop/bag":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["handbag","purse"],"tags":{"shop":"bag"},"name":"Bag/Luggage Store"},"shop/bakery":{"icon":"bakery","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"bakery"},"name":"Bakery"},"shop/bathroom_furnishing":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"bathroom_furnishing"},"name":"Bathroom Furnishing Store"},"shop/beauty":{"icon":"shop","fields":["operator","address","building_area","opening_hours","beauty"],"geometry":["point","area"],"terms":["spa","salon","tanning"],"tags":{"shop":"beauty"},"name":"Beauty Shop"},"shop/beauty/nails":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["manicure","pedicure"],"tags":{"shop":"beauty","beauty":"nails"},"name":"Nail Salon"},"shop/beauty/tanning":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"beauty","beauty":"tanning"},"name":"Tanning Salon"},"shop/bed":{"icon":"lodging","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"bed"},"name":"Bedding/Mattress Store"},"shop/beverages":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"beverages"},"name":"Beverage Store"},"shop/bicycle":{"icon":"bicycle","fields":["operator","address","building_area","opening_hours","service/bicycle"],"geometry":["point","area"],"terms":["bike","repair"],"tags":{"shop":"bicycle"},"name":"Bicycle Shop"},"shop/bookmaker":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["betting"],"tags":{"shop":"bookmaker"},"name":"Bookmaker"},"shop/books":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"books"},"name":"Book Store"},"shop/boutique":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"boutique"},"name":"Boutique"},"shop/butcher":{"icon":"slaughterhouse","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["meat"],"tags":{"shop":"butcher"},"name":"Butcher"},"shop/candles":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"candles"},"name":"Candle Shop"},"shop/car_parts":{"icon":"car","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["auto"],"tags":{"shop":"car_parts"},"name":"Car Parts Store"},"shop/car_repair":{"icon":"car","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["auto","garage","service"],"tags":{"shop":"car_repair"},"name":"Car Repair Shop"},"shop/car":{"icon":"car","fields":["operator","address","building_area","opening_hours","second_hand"],"geometry":["point","area"],"terms":["auto"],"tags":{"shop":"car"},"name":"Car Dealership"},"shop/carpet":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["rug"],"tags":{"shop":"carpet"},"name":"Carpet Store"},"shop/charity":{"icon":"shop","fields":["operator","address","building_area","opening_hours","second_hand"],"geometry":["point","area"],"terms":["thrift","op shop","nonprofit"],"tags":{"shop":"charity"},"name":"Charity Store"},"shop/cheese":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"cheese"},"name":"Cheese Store"},"shop/chemist":{"icon":"grocery","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"chemist"},"terms":["med*","drug*","gift"],"name":"Drugstore"},"shop/chocolate":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"chocolate"},"name":"Chocolate Store"},"shop/clothes":{"icon":"clothing-store","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"clothes"},"name":"Clothing Store"},"shop/coffee":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"coffee"},"name":"Coffee Store"},"shop/computer":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"computer"},"name":"Computer Store"},"shop/confectionery":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"confectionery"},"name":"Candy Store"},"shop/convenience":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"convenience"},"name":"Convenience Store"},"shop/copyshop":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"copyshop"},"name":"Copy Store"},"shop/cosmetics":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"cosmetics"},"name":"Cosmetics Store"},"shop/craft":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"craft"},"terms":["art*","paint*","frame"],"name":"Arts and Crafts Store"},"shop/curtain":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["drape*","window"],"tags":{"shop":"curtain"},"name":"Curtain Store"},"shop/dairy":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["milk","egg","cheese"],"tags":{"shop":"dairy"},"name":"Dairy Store"},"shop/deli":{"icon":"restaurant","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["lunch","meat","sandwich"],"tags":{"shop":"deli"},"name":"Deli"},"shop/department_store":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"department_store"},"name":"Department Store"},"shop/doityourself":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"doityourself"},"name":"DIY Store"},"shop/dry_cleaning":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"dry_cleaning"},"name":"Dry Cleaner"},"shop/e-cigarette":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"e-cigarette"},"terms":["electronic","vapor"],"name":"E-Cigarette Shop"},"shop/electronics":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["appliance","audio","computer","tv"],"tags":{"shop":"electronics"},"name":"Electronics Store"},"shop/erotic":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["sex","porn"],"tags":{"shop":"erotic"},"name":"Erotic Store"},"shop/fabric":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["sew"],"tags":{"shop":"fabric"},"name":"Fabric Store"},"shop/farm":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["farm shop","farm stand"],"tags":{"shop":"farm"},"name":"Produce Stand"},"shop/fashion":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"fashion"},"name":"Fashion Store"},"shop/florist":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["flower"],"tags":{"shop":"florist"},"name":"Florist"},"shop/frame":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"frame"},"terms":["art*","paint*","photo*","frame"],"name":"Framing Shop"},"shop/funeral_directors":{"icon":"cemetery","fields":["operator","address","building_area","religion","denomination"],"geometry":["point","area"],"terms":["undertaker","memorial home"],"tags":{"shop":"funeral_directors"},"name":"Funeral Home"},"shop/furnace":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["oven","stove"],"tags":{"shop":"furnace"},"name":"Furnace Store"},"shop/furniture":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["chair","sofa","table"],"tags":{"shop":"furniture"},"name":"Furniture Store"},"shop/garden_centre":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["landscape","mulch","shrub","tree"],"tags":{"shop":"garden_centre"},"name":"Garden Center"},"shop/gift":{"icon":"gift","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["souvenir"],"tags":{"shop":"gift"},"name":"Gift Shop"},"shop/greengrocer":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["fruit","vegetable"],"tags":{"shop":"greengrocer"},"name":"Greengrocer"},"shop/hairdresser":{"icon":"hairdresser","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["barber"],"tags":{"shop":"hairdresser"},"name":"Hairdresser"},"shop/hardware":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"hardware"},"name":"Hardware Store"},"shop/hearing_aids":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"hearing_aids"},"name":"Hearing Aids Store"},"shop/herbalist":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"herbalist"},"name":"Herbalist"},"shop/hifi":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["stereo","video"],"tags":{"shop":"hifi"},"name":"Hifi Store"},"shop/houseware":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["home","household"],"tags":{"shop":"houseware"},"name":"Houseware Store"},"shop/interior_decoration":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"interior_decoration"},"name":"Interior Decoration Store"},"shop/jewelry":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["diamond","gem","ring"],"tags":{"shop":"jewelry"},"name":"Jeweler"},"shop/kiosk":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"kiosk"},"name":"News Kiosk"},"shop/kitchen":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"kitchen"},"name":"Kitchen Design Store"},"shop/laundry":{"icon":"laundry","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"laundry"},"name":"Laundry"},"shop/leather":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"leather"},"name":"Leather Store"},"shop/locksmith":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["key","lockpick"],"tags":{"shop":"locksmith"},"name":"Locksmith"},"shop/lottery":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"lottery"},"name":"Lottery Shop"},"shop/mall":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["shopping"],"tags":{"shop":"mall"},"name":"Mall"},"shop/massage":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"massage"},"name":"Massage Shop"},"shop/medical_supply":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"medical_supply"},"name":"Medical Supply Store"},"shop/mobile_phone":{"icon":"mobilephone","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"mobile_phone"},"name":"Mobile Phone Store"},"shop/money_lender":{"icon":"bank","fields":["operator","address","building_area","opening_hours","currency_multi"],"geometry":["point","area"],"tags":{"shop":"money_lender"},"name":"Money Lender"},"shop/motorcycle":{"icon":"scooter","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["bike"],"tags":{"shop":"motorcycle"},"name":"Motorcycle Dealership"},"shop/music":{"icon":"music","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["CD","vinyl"],"tags":{"shop":"music"},"name":"Music Store"},"shop/musical_instrument":{"icon":"music","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["guitar"],"tags":{"shop":"musical_instrument"},"name":"Musical Instrument Store"},"shop/newsagent":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"newsagent"},"name":"Newspaper/Magazine Shop"},"shop/nutrition_supplements":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"nutrition_supplements"},"name":"Nutrition Supplements Store"},"shop/optician":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["eye","glasses"],"tags":{"shop":"optician"},"name":"Optician"},"shop/organic":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"supermarket","organic":"only"},"name":"Organic Goods Store"},"shop/outdoor":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["camping","climbing","hiking"],"tags":{"shop":"outdoor"},"name":"Outdoors Store"},"shop/paint":{"icon":"water","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"paint"},"name":"Paint Store"},"shop/pastry":{"icon":"bakery","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"pastry"},"terms":["patisserie","cake shop","cakery"],"name":"Pastry Shop"},"shop/pawnbroker":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"pawnbroker"},"name":"Pawn Shop"},"shop/pet":{"icon":"dog-park","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["cat","dog","fish"],"tags":{"shop":"pet"},"name":"Pet Store"},"shop/photo":{"icon":"camera","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["camera","film"],"tags":{"shop":"photo"},"name":"Photography Store"},"shop/pyrotechnics":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"pyrotechnics"},"name":"Fireworks Store"},"shop/radiotechnics":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"radiotechnics"},"name":"Radio/Electronic Component Store"},"shop/religion":{"icon":"shop","fields":["operator","address","building_area","opening_hours","religion","denomination"],"geometry":["point","area"],"tags":{"shop":"religion"},"name":"Religious Store"},"shop/scuba_diving":{"icon":"swimming","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"scuba_diving"},"name":"Scuba Diving Shop"},"shop/seafood":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["fishmonger"],"tags":{"shop":"seafood"},"name":"Seafood Shop"},"shop/second_hand":{"icon":"shop","fields":["operator","address","building_area","opening_hours","second_hand"],"geometry":["point","area"],"terms":["secondhand","second hand","resale","thrift","used"],"tags":{"shop":"second_hand"},"name":"Consignment/Thrift Store"},"shop/shoes":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"shoes"},"name":"Shoe Store"},"shop/sports":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"sports"},"name":"Sporting Goods Store"},"shop/stationery":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["card","paper"],"tags":{"shop":"stationery"},"name":"Stationery Store"},"shop/storage_rental":{"icon":"shop","fields":["operator","address","building","opening_hours"],"geometry":["point","area"],"tags":{"shop":"storage_rental"},"name":"Storage Rental"},"shop/supermarket":{"icon":"grocery","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["grocery","store","shop"],"tags":{"shop":"supermarket"},"name":"Supermarket"},"shop/tailor":{"icon":"clothing-store","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["clothes","suit"],"tags":{"shop":"tailor"},"name":"Tailor"},"shop/tattoo":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"tattoo"},"name":"Tattoo Parlor"},"shop/tea":{"icon":"cafe","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"tea"},"name":"Tea Store"},"shop/ticket":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"ticket"},"name":"Ticket Seller"},"shop/tobacco":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"tobacco"},"name":"Tobacco Shop"},"shop/toys":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"toys"},"name":"Toy Store"},"shop/travel_agency":{"icon":"suitcase","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"travel_agency"},"name":"Travel Agency"},"shop/tyres":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"tyres"},"name":"Tire Store"},"shop/vacuum_cleaner":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"vacuum_cleaner"},"name":"Vacuum Cleaner Store"},"shop/variety_store":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"variety_store"},"name":"Variety Store"},"shop/video_games":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"video_games"},"name":"Video Game Store"},"shop/video":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["DVD"],"tags":{"shop":"video"},"name":"Video Store"},"shop/water_sports":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"water_sports"},"name":"Watersport/Swim Shop"},"shop/weapons":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["ammo","gun","knife","knives"],"tags":{"shop":"weapons"},"name":"Weapon Shop"},"shop/window_blind":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"window_blind"},"name":"Window Blind Store"},"shop/wine":{"icon":"alcohol-shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"wine"},"name":"Wine Shop"},"tourism":{"fields":["tourism"],"geometry":["point","vertex","area"],"tags":{"tourism":"*"},"name":"Tourism"},"tourism/alpine_hut":{"icon":"lodging","fields":["operator","address","building_area"],"geometry":["point","area"],"tags":{"tourism":"alpine_hut"},"name":"Alpine Hut"},"tourism/apartment":{"icon":"lodging","fields":["operator","address","building_area","smoking","rooms","internet_access","internet_access/fee"],"geometry":["point","area"],"tags":{"tourism":"apartment"},"name":"Guest Apartment / Condo"},"tourism/artwork":{"icon":"art-gallery","fields":["artwork_type","artist"],"geometry":["point","vertex","area"],"tags":{"tourism":"artwork"},"terms":["mural","sculpture","statue"],"name":"Artwork"},"tourism/attraction":{"icon":"monument","fields":["operator","address"],"geometry":["point","vertex","area"],"tags":{"tourism":"attraction"},"name":"Tourist Attraction"},"tourism/camp_site":{"icon":"campsite","fields":["operator","address","capacity","fee"],"geometry":["point","vertex","area"],"terms":["tent","rv"],"tags":{"tourism":"camp_site"},"name":"Campground"},"tourism/caravan_site":{"icon":"bus","fields":["operator","address","capacity","fee","sanitary_dump_station","power_supply","internet_access"],"geometry":["point","vertex","area"],"terms":["Motor Home","Camper"],"tags":{"tourism":"caravan_site"},"name":"RV Park"},"tourism/chalet":{"icon":"lodging","fields":["operator","address","building_area","smoking"],"geometry":["point","area"],"tags":{"tourism":"chalet"},"name":"Chalet"},"tourism/gallery":{"icon":"art-gallery","fields":["artwork_type","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["art*","exhibit*","paint*","photo*","sculpt*"],"tags":{"tourism":"gallery"},"name":"Art Gallery"},"tourism/guest_house":{"icon":"lodging","fields":["operator","address","building_area","smoking","rooms","internet_access","internet_access/fee"],"geometry":["point","area"],"tags":{"tourism":"guest_house"},"terms":["B&B","Bed and Breakfast"],"name":"Guest House"},"tourism/hostel":{"icon":"lodging","fields":["operator","address","building_area","smoking","rooms","internet_access","internet_access/fee"],"geometry":["point","area"],"tags":{"tourism":"hostel"},"name":"Hostel"},"tourism/hotel":{"icon":"lodging","fields":["operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee"],"geometry":["point","area"],"tags":{"tourism":"hotel"},"name":"Hotel"},"tourism/information":{"fields":["information","operator","address","building_area"],"geometry":["point","vertex","area"],"tags":{"tourism":"information"},"name":"Information"},"tourism/information/board":{"fields":["operator","board_type"],"geometry":["point","vertex"],"tags":{"tourism":"information","information":"board"},"name":"Information Board"},"tourism/information/guidepost":{"fields":["operator","ref"],"geometry":["point","vertex"],"tags":{"tourism":"information","information":"guidepost"},"name":"Guidepost"},"tourism/information/map":{"fields":["operator","map_type","map_size"],"geometry":["point","vertex"],"tags":{"tourism":"information","information":"map"},"name":"Map"},"tourism/information/office":{"fields":["operator","address","building_area"],"geometry":["point","vertex","area"],"tags":{"tourism":"information","information":"office"},"name":"Tourist Information Office"},"tourism/motel":{"icon":"lodging","fields":["operator","address","building_area","smoking","rooms","internet_access","internet_access/fee"],"geometry":["point","area"],"tags":{"tourism":"motel"},"name":"Motel"},"tourism/museum":{"icon":"museum","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["art*","exhibit*","gallery","foundation","hall","institution","paint*","photo*","sculpt*"],"tags":{"tourism":"museum"},"name":"Museum"},"tourism/picnic_site":{"icon":"park","fields":["operator","address","smoking"],"geometry":["point","vertex","area"],"terms":["camp"],"tags":{"tourism":"picnic_site"},"name":"Picnic Site"},"tourism/theme_park":{"fields":["operator","address","opening_hours"],"geometry":["point","area"],"tags":{"tourism":"theme_park"},"name":"Theme Park"},"tourism/viewpoint":{"geometry":["point","vertex"],"tags":{"tourism":"viewpoint"},"name":"Viewpoint"},"tourism/zoo":{"icon":"zoo","fields":["operator","address","opening_hours"],"geometry":["point","area"],"tags":{"tourism":"zoo"},"name":"Zoo"},"traffic_calming":{"fields":["traffic_calming","parallel_direction"],"geometry":["vertex","line"],"tags":{"traffic_calming":"*"},"terms":["bump","hump","slow","speed"],"name":"Traffic Calming"},"traffic_calming/bump":{"fields":["surface","parallel_direction"],"geometry":["vertex","line"],"terms":["hump","speed","slow"],"tags":{"traffic_calming":"bump"},"name":"Speed Bump"},"traffic_calming/chicane":{"fields":["parallel_direction"],"geometry":["vertex","line"],"terms":["driveway link","speed","slow"],"tags":{"traffic_calming":"chicane"},"name":"Traffic Chicane"},"traffic_calming/choker":{"fields":["parallel_direction"],"geometry":["vertex","line"],"terms":["speed","slow"],"tags":{"traffic_calming":"choker"},"name":"Traffic Choker"},"traffic_calming/cushion":{"fields":["surface","parallel_direction"],"geometry":["vertex","line"],"terms":["bump","hump","speed","slow"],"tags":{"traffic_calming":"cushion"},"name":"Speed Cushion"},"traffic_calming/dip":{"fields":["surface","parallel_direction"],"geometry":["vertex","line"],"terms":["speed","slow"],"tags":{"traffic_calming":"dip"},"name":"Dip"},"traffic_calming/hump":{"fields":["surface","parallel_direction"],"geometry":["vertex","line"],"terms":["bump","speed","slow"],"tags":{"traffic_calming":"hump"},"name":"Speed Hump"},"traffic_calming/island":{"icon":"circle","geometry":["vertex"],"terms":["circle","roundabout","slow"],"tags":{"traffic_calming":"island"},"name":"Traffic Island"},"traffic_calming/rumble_strip":{"fields":["parallel_direction"],"geometry":["vertex","line"],"terms":["audible lines","sleeper lines","growlers"],"tags":{"traffic_calming":"rumble_strip"},"name":"Rumble Strip"},"traffic_calming/table":{"fields":["surface"],"geometry":["vertex","line"],"terms":["flat top","hump","speed","slow"],"tags":{"highway":"crossing","traffic_calming":"table"},"name":"Raised Pedestrian Crossing"},"type/multipolygon":{"geometry":["area","relation"],"tags":{"type":"multipolygon"},"removeTags":{},"name":"Multipolygon","icon":"multipolygon","searchable":false,"matchScore":0.1},"type/boundary":{"geometry":["relation"],"tags":{"type":"boundary"},"name":"Boundary","icon":"boundary","fields":["boundary"]},"type/boundary/administrative":{"name":"Administrative Boundary","geometry":["relation"],"tags":{"type":"boundary","boundary":"administrative"},"fields":["admin_level"],"icon":"boundary"},"type/restriction":{"geometry":["relation"],"tags":{"type":"restriction"},"name":"Restriction","icon":"restriction","fields":["restriction","except"]},"type/restriction/no_left_turn":{"name":"No Left Turn","geometry":["relation"],"tags":{"type":"restriction","restriction":"no_left_turn"},"fields":["except"],"icon":"restriction-no-left-turn"},"type/restriction/no_right_turn":{"name":"No Right Turn","geometry":["relation"],"tags":{"type":"restriction","restriction":"no_right_turn"},"fields":["except"],"icon":"restriction-no-right-turn"},"type/restriction/no_straight_on":{"name":"No Straight On","geometry":["relation"],"tags":{"type":"restriction","restriction":"no_straight_on"},"fields":["except"],"icon":"restriction-no-straight-on"},"type/restriction/no_u_turn":{"name":"No U-turn","geometry":["relation"],"tags":{"type":"restriction","restriction":"no_u_turn"},"fields":["except"],"icon":"restriction-no-u-turn"},"type/restriction/only_left_turn":{"name":"Left Turn Only","geometry":["relation"],"tags":{"type":"restriction","restriction":"only_left_turn"},"fields":["except"],"icon":"restriction-only-left-turn"},"type/restriction/only_right_turn":{"name":"Right Turn Only","geometry":["relation"],"tags":{"type":"restriction","restriction":"only_right_turn"},"fields":["except"],"icon":"restriction-only-right-turn"},"type/restriction/only_straight_on":{"name":"No Turns","geometry":["relation"],"tags":{"type":"restriction","restriction":"only_straight_on"},"fields":["except"],"icon":"restriction-only-straight-on"},"type/route_master":{"geometry":["relation"],"tags":{"type":"route_master"},"name":"Route Master","icon":"route-master","fields":["route_master","ref","operator","network"]},"type/route":{"geometry":["relation"],"tags":{"type":"route"},"name":"Route","icon":"route","fields":["route","ref","operator","network"]},"type/route/bicycle":{"geometry":["relation"],"tags":{"type":"route","route":"bicycle"},"name":"Cycle Route","icon":"route-bicycle","fields":["ref","network_bicycle","cycle_network"]},"type/route/bus":{"geometry":["relation"],"tags":{"type":"route","route":"bus"},"name":"Bus Route","icon":"route-bus","fields":["ref","operator","network"]},"type/route/detour":{"geometry":["relation"],"tags":{"type":"route","route":"detour"},"name":"Detour Route","icon":"route-detour","fields":["ref"]},"type/route/ferry":{"geometry":["relation"],"tags":{"type":"route","route":"ferry"},"name":"Ferry Route","icon":"route-ferry","fields":["ref","operator","network"]},"type/route/foot":{"geometry":["relation"],"tags":{"type":"route","route":"foot"},"name":"Foot Route","icon":"route-foot","fields":["ref","operator","network_foot"]},"type/route/hiking":{"geometry":["relation"],"tags":{"type":"route","route":"hiking"},"name":"Hiking Route","icon":"route-foot","fields":["ref","operator","network_foot"]},"type/route/horse":{"geometry":["relation"],"tags":{"type":"route","route":"horse"},"name":"Riding Route","icon":"route-horse","fields":["ref","operator","network_horse"]},"type/route/pipeline":{"geometry":["relation"],"tags":{"type":"route","route":"pipeline"},"name":"Pipeline Route","icon":"route-pipeline","fields":["ref","operator"]},"type/route/power":{"geometry":["relation"],"tags":{"type":"route","route":"power"},"name":"Power Route","icon":"route-power","fields":["ref","operator"]},"type/route/road":{"geometry":["relation"],"tags":{"type":"route","route":"road"},"name":"Road Route","icon":"route-road","fields":["ref","network_road"]},"type/route/train":{"geometry":["relation"],"tags":{"type":"route","route":"train"},"name":"Train Route","icon":"route-train","fields":["ref","operator","network"]},"type/route/tram":{"geometry":["relation"],"tags":{"type":"route","route":"tram"},"name":"Tram Route","icon":"route-tram","fields":["ref","operator","network"]},"type/site":{"geometry":["relation"],"tags":{"type":"site"},"name":"Site","icon":"relation","fields":["site"]},"vertex":{"name":"Other","tags":{},"geometry":["vertex"],"matchScore":0.1},"waterway/boatyard":{"icon":"harbor","fields":["operator"],"geometry":["area","vertex","point"],"tags":{"waterway":"boatyard"},"name":"Boatyard"},"waterway/canal":{"icon":"waterway-canal","fields":["width"],"geometry":["line"],"tags":{"waterway":"canal"},"name":"Canal"},"waterway/dam":{"icon":"dam","geometry":["point","vertex","line","area"],"tags":{"waterway":"dam"},"name":"Dam"},"waterway/ditch":{"icon":"waterway-ditch","fields":["tunnel"],"geometry":["line"],"tags":{"waterway":"ditch"},"name":"Ditch"},"waterway/dock":{"icon":"harbor","fields":["dock","operator"],"geometry":["area","vertex","point"],"terms":["boat","ship","vessel","marine"],"tags":{"waterway":"dock"},"name":"Wet Dock / Dry Dock"},"waterway/drain":{"icon":"waterway-stream","fields":["tunnel"],"geometry":["line"],"tags":{"waterway":"drain"},"name":"Drain"},"waterway/fuel":{"icon":"fuel","fields":["operator","address","opening_hours","fuel_multi"],"geometry":["point","area"],"terms":["petrol","gas","diesel","boat"],"tags":{"waterway":"fuel"},"name":"Marine Fuel Station"},"waterway/river":{"icon":"waterway-river","fields":["tunnel","width"],"geometry":["line"],"terms":["beck","branch","brook","course","creek","estuary","rill","rivulet","run","runnel","stream","tributary","watercourse"],"tags":{"waterway":"river"},"name":"River"},"waterway/riverbank":{"icon":"water","geometry":["area"],"tags":{"waterway":"riverbank"},"name":"Riverbank"},"waterway/sanitary_dump_station":{"fields":["operator","access_toilets","fee","water_point"],"geometry":["point","vertex","area"],"terms":["Boat","Watercraft","Sanitary","Dump Station","Pumpout","Pump out","Elsan","CDP","CTDP","Chemical Toilet"],"tags":{"waterway":"sanitary_dump_station"},"name":"Marine Toilet Disposal"},"waterway/stream":{"icon":"waterway-stream","fields":["tunnel","width"],"geometry":["line"],"terms":["beck","branch","brook","burn","course","creek","current","drift","flood","flow","freshet","race","rill","rindle","rivulet","run","runnel","rush","spate","spritz","surge","tide","torrent","tributary","watercourse"],"tags":{"waterway":"stream"},"name":"Stream"},"waterway/water_point":{"icon":"water","geometry":["area","vertex","point"],"tags":{"waterway":"water_point"},"name":"Marine Drinking Water"},"waterway/weir":{"icon":"dam","geometry":["vertex","line"],"tags":{"waterway":"weir"},"name":"Weir"},"amenity/fuel/76":{"tags":{"name":"76","amenity":"fuel"},"name":"76","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Neste":{"tags":{"name":"Neste","amenity":"fuel"},"name":"Neste","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/BP":{"tags":{"name":"BP","amenity":"fuel"},"name":"BP","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Shell":{"tags":{"name":"Shell","amenity":"fuel"},"name":"Shell","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Agip":{"tags":{"name":"Agip","amenity":"fuel"},"name":"Agip","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Migrol":{"tags":{"name":"Migrol","amenity":"fuel"},"name":"Migrol","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Avia":{"tags":{"name":"Avia","amenity":"fuel"},"name":"Avia","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Texaco":{"tags":{"name":"Texaco","amenity":"fuel"},"name":"Texaco","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Total":{"tags":{"name":"Total","amenity":"fuel"},"name":"Total","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Statoil":{"tags":{"name":"Statoil","amenity":"fuel"},"name":"Statoil","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Esso":{"tags":{"name":"Esso","amenity":"fuel"},"name":"Esso","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Jet":{"tags":{"name":"Jet","amenity":"fuel"},"name":"Jet","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Avanti":{"tags":{"name":"Avanti","amenity":"fuel"},"name":"Avanti","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/OMV":{"tags":{"name":"OMV","amenity":"fuel"},"name":"OMV","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Aral":{"tags":{"name":"Aral","amenity":"fuel"},"name":"Aral","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/JET":{"tags":{"name":"JET","amenity":"fuel"},"name":"JET","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/United":{"tags":{"name":"United","amenity":"fuel"},"name":"United","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Mobil":{"tags":{"name":"Mobil","amenity":"fuel"},"name":"Mobil","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Caltex":{"tags":{"name":"Caltex","amenity":"fuel"},"name":"Caltex","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Sunoco":{"tags":{"name":"Sunoco","amenity":"fuel"},"name":"Sunoco","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Q8":{"tags":{"name":"Q8","amenity":"fuel"},"name":"Q8","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ARAL":{"tags":{"name":"ARAL","amenity":"fuel"},"name":"ARAL","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/CEPSA":{"tags":{"name":"CEPSA","amenity":"fuel"},"name":"CEPSA","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/BFT":{"tags":{"name":"BFT","amenity":"fuel"},"name":"BFT","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petron":{"tags":{"name":"Petron","amenity":"fuel"},"name":"Petron","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Total Access":{"tags":{"name":"Total Access","amenity":"fuel"},"name":"Total Access","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Elf":{"tags":{"name":"Elf","amenity":"fuel"},"name":"Elf","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Station Service E. Leclerc":{"tags":{"name":"Station Service E. Leclerc","amenity":"fuel"},"name":"Station Service E. Leclerc","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Shell Express":{"tags":{"name":"Shell Express","amenity":"fuel"},"name":"Shell Express","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Hess":{"tags":{"name":"Hess","amenity":"fuel"},"name":"Hess","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Flying V":{"tags":{"name":"Flying V","amenity":"fuel"},"name":"Flying V","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/bft":{"tags":{"name":"bft","amenity":"fuel"},"name":"bft","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Gulf":{"tags":{"name":"Gulf","amenity":"fuel"},"name":"Gulf","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/PTT":{"tags":{"name":"PTT","amenity":"fuel"},"name":"PTT","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/St1":{"tags":{"name":"St1","amenity":"fuel"},"name":"St1","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Teboil":{"tags":{"name":"Teboil","amenity":"fuel"},"name":"Teboil","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/HEM":{"tags":{"name":"HEM","amenity":"fuel"},"name":"HEM","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/GALP":{"tags":{"name":"GALP","amenity":"fuel"},"name":"GALP","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/OK":{"tags":{"name":"OK","amenity":"fuel"},"name":"OK","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ÖMV":{"tags":{"name":"ÖMV","amenity":"fuel"},"name":"ÖMV","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Tinq":{"tags":{"name":"Tinq","amenity":"fuel"},"name":"Tinq","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/OKQ8":{"tags":{"name":"OKQ8","amenity":"fuel"},"name":"OKQ8","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Repsol":{"tags":{"name":"Repsol","amenity":"fuel"},"name":"Repsol","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Westfalen":{"tags":{"name":"Westfalen","amenity":"fuel"},"name":"Westfalen","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Esso Express":{"tags":{"name":"Esso Express","amenity":"fuel"},"name":"Esso Express","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Tamoil":{"tags":{"name":"Tamoil","amenity":"fuel"},"name":"Tamoil","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Engen":{"tags":{"name":"Engen","amenity":"fuel"},"name":"Engen","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Sasol":{"tags":{"name":"Sasol","amenity":"fuel"},"name":"Sasol","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Topaz":{"tags":{"name":"Topaz","amenity":"fuel"},"name":"Topaz","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/LPG":{"tags":{"name":"LPG","amenity":"fuel"},"name":"LPG","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Orlen":{"tags":{"name":"Orlen","amenity":"fuel"},"name":"Orlen","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Oilibya":{"tags":{"name":"Oilibya","amenity":"fuel"},"name":"Oilibya","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Tango":{"tags":{"name":"Tango","amenity":"fuel"},"name":"Tango","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Star":{"tags":{"name":"Star","amenity":"fuel"},"name":"Star","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Петрол":{"tags":{"name":"Петрол","amenity":"fuel"},"name":"Петрол","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Cepsa":{"tags":{"name":"Cepsa","amenity":"fuel"},"name":"Cepsa","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/OIL!":{"tags":{"name":"OIL!","amenity":"fuel"},"name":"OIL!","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Ultramar":{"tags":{"name":"Ultramar","amenity":"fuel"},"name":"Ultramar","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Irving":{"tags":{"name":"Irving","amenity":"fuel"},"name":"Irving","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Lukoil":{"tags":{"name":"Lukoil","amenity":"fuel"},"name":"Lukoil","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petro-Canada":{"tags":{"name":"Petro-Canada","amenity":"fuel"},"name":"Petro-Canada","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Agrola":{"tags":{"name":"Agrola","amenity":"fuel"},"name":"Agrola","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Husky":{"tags":{"name":"Husky","amenity":"fuel"},"name":"Husky","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Slovnaft":{"tags":{"name":"Slovnaft","amenity":"fuel"},"name":"Slovnaft","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Sheetz":{"tags":{"name":"Sheetz","amenity":"fuel"},"name":"Sheetz","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Mol":{"tags":{"name":"Mol","amenity":"fuel"},"name":"Mol","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petronas":{"tags":{"name":"Petronas","amenity":"fuel"},"name":"Petronas","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Газпромнефть":{"tags":{"name":"Газпромнефть","amenity":"fuel"},"name":"Газпромнефть","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Лукойл":{"tags":{"name":"Лукойл","amenity":"fuel"},"name":"Лукойл","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Elan":{"tags":{"name":"Elan","amenity":"fuel"},"name":"Elan","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Роснефть":{"tags":{"name":"Роснефть","amenity":"fuel"},"name":"Роснефть","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Turmöl":{"tags":{"name":"Turmöl","amenity":"fuel"},"name":"Turmöl","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Neste A24":{"tags":{"name":"Neste A24","amenity":"fuel"},"name":"Neste A24","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Marathon":{"tags":{"name":"Marathon","amenity":"fuel"},"name":"Marathon","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Valero":{"tags":{"name":"Valero","amenity":"fuel"},"name":"Valero","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Eni":{"tags":{"name":"Eni","amenity":"fuel"},"name":"Eni","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Chevron":{"tags":{"name":"Chevron","amenity":"fuel"},"name":"Chevron","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ТНК":{"tags":{"name":"ТНК","amenity":"fuel"},"name":"ТНК","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/REPSOL":{"tags":{"name":"REPSOL","amenity":"fuel"},"name":"REPSOL","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/MOL":{"tags":{"name":"MOL","amenity":"fuel"},"name":"MOL","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Bliska":{"tags":{"name":"Bliska","amenity":"fuel"},"name":"Bliska","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Api":{"tags":{"name":"Api","amenity":"fuel"},"name":"Api","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Arco":{"tags":{"name":"Arco","amenity":"fuel"},"name":"Arco","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Pemex":{"tags":{"name":"Pemex","amenity":"fuel"},"name":"Pemex","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Exxon":{"tags":{"name":"Exxon","amenity":"fuel"},"name":"Exxon","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Coles Express":{"tags":{"name":"Coles Express","amenity":"fuel"},"name":"Coles Express","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petrom":{"tags":{"name":"Petrom","amenity":"fuel"},"name":"Petrom","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/PETRONOR":{"tags":{"name":"PETRONOR","amenity":"fuel"},"name":"PETRONOR","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Rompetrol":{"tags":{"name":"Rompetrol","amenity":"fuel"},"name":"Rompetrol","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Lotos":{"tags":{"name":"Lotos","amenity":"fuel"},"name":"Lotos","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ОМВ":{"tags":{"name":"ОМВ","amenity":"fuel"},"name":"ОМВ","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/BR":{"tags":{"name":"BR","amenity":"fuel"},"name":"BR","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Copec":{"tags":{"name":"Copec","amenity":"fuel"},"name":"Copec","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petrobras":{"tags":{"name":"Petrobras","amenity":"fuel"},"name":"Petrobras","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Liberty":{"tags":{"name":"Liberty","amenity":"fuel"},"name":"Liberty","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/IP":{"tags":{"name":"IP","amenity":"fuel"},"name":"IP","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Erg":{"tags":{"name":"Erg","amenity":"fuel"},"name":"Erg","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Eneos":{"tags":{"name":"Eneos","amenity":"fuel"},"name":"Eneos","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Citgo":{"tags":{"name":"Citgo","amenity":"fuel"},"name":"Citgo","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Metano":{"tags":{"name":"Metano","amenity":"fuel"},"name":"Metano","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Сургутнефтегаз":{"tags":{"name":"Сургутнефтегаз","amenity":"fuel"},"name":"Сургутнефтегаз","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/EKO":{"tags":{"name":"EKO","amenity":"fuel"},"name":"EKO","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Eko":{"tags":{"name":"Eko","amenity":"fuel"},"name":"Eko","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Indipend.":{"tags":{"name":"Indipend.","amenity":"fuel"},"name":"Indipend.","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/IES":{"tags":{"name":"IES","amenity":"fuel"},"name":"IES","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/TotalErg":{"tags":{"name":"TotalErg","amenity":"fuel"},"name":"TotalErg","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Cenex":{"tags":{"name":"Cenex","amenity":"fuel"},"name":"Cenex","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ПТК":{"tags":{"name":"ПТК","amenity":"fuel"},"name":"ПТК","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/HP":{"tags":{"name":"HP","amenity":"fuel"},"name":"HP","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Phillips 66":{"tags":{"name":"Phillips 66","amenity":"fuel"},"name":"Phillips 66","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/CARREFOUR":{"tags":{"name":"CARREFOUR","amenity":"fuel"},"name":"CARREFOUR","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ERG":{"tags":{"name":"ERG","amenity":"fuel"},"name":"ERG","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Speedway":{"tags":{"name":"Speedway","amenity":"fuel"},"name":"Speedway","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Benzina":{"tags":{"name":"Benzina","amenity":"fuel"},"name":"Benzina","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Татнефть":{"tags":{"name":"Татнефть","amenity":"fuel"},"name":"Татнефть","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Terpel":{"tags":{"name":"Terpel","amenity":"fuel"},"name":"Terpel","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/WOG":{"tags":{"name":"WOG","amenity":"fuel"},"name":"WOG","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Seaoil":{"tags":{"name":"Seaoil","amenity":"fuel"},"name":"Seaoil","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/АЗС":{"tags":{"name":"АЗС","amenity":"fuel"},"name":"АЗС","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Kwik Trip":{"tags":{"name":"Kwik Trip","amenity":"fuel"},"name":"Kwik Trip","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Pertamina":{"tags":{"name":"Pertamina","amenity":"fuel"},"name":"Pertamina","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/COSMO":{"tags":{"name":"COSMO","amenity":"fuel"},"name":"COSMO","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Z":{"tags":{"name":"Z","amenity":"fuel"},"name":"Z","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Indian Oil":{"tags":{"name":"Indian Oil","amenity":"fuel"},"name":"Indian Oil","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/АГЗС":{"tags":{"name":"АГЗС","amenity":"fuel"},"name":"АГЗС","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/INA":{"tags":{"name":"INA","amenity":"fuel"},"name":"INA","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/JOMO":{"tags":{"name":"JOMO","amenity":"fuel"},"name":"JOMO","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Holiday":{"tags":{"name":"Holiday","amenity":"fuel"},"name":"Holiday","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/YPF":{"tags":{"name":"YPF","amenity":"fuel"},"name":"YPF","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/IDEMITSU":{"tags":{"name":"IDEMITSU","amenity":"fuel"},"name":"IDEMITSU","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ENEOS":{"tags":{"name":"ENEOS","amenity":"fuel"},"name":"ENEOS","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Bharat Petroleum":{"tags":{"name":"Bharat Petroleum","amenity":"fuel"},"name":"Bharat Petroleum","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/CAMPSA":{"tags":{"name":"CAMPSA","amenity":"fuel"},"name":"CAMPSA","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Casey's General Store":{"tags":{"name":"Casey's General Store","amenity":"fuel"},"name":"Casey's General Store","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Башнефть":{"tags":{"name":"Башнефть","amenity":"fuel"},"name":"Башнефть","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Kangaroo":{"tags":{"name":"Kangaroo","amenity":"fuel"},"name":"Kangaroo","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/コスモ石油 (COSMO)":{"tags":{"name":"コスモ石油 (COSMO)","amenity":"fuel"},"name":"コスモ石油 (COSMO)","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/MEROIL":{"tags":{"name":"MEROIL","amenity":"fuel"},"name":"MEROIL","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/1-2-3":{"tags":{"name":"1-2-3","amenity":"fuel"},"name":"1-2-3","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/出光":{"tags":{"name":"出光","name:en":"IDEMITSU","amenity":"fuel"},"name":"出光","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/НК Альянс":{"tags":{"name":"НК Альянс","amenity":"fuel"},"name":"НК Альянс","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Sinclair":{"tags":{"name":"Sinclair","amenity":"fuel"},"name":"Sinclair","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Conoco":{"tags":{"name":"Conoco","amenity":"fuel"},"name":"Conoco","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/SPBU":{"tags":{"name":"SPBU","amenity":"fuel"},"name":"SPBU","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Макпетрол":{"tags":{"name":"Макпетрол","amenity":"fuel"},"name":"Макпетрол","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Posto Ipiranga":{"tags":{"name":"Posto Ipiranga","amenity":"fuel"},"name":"Posto Ipiranga","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Posto Shell":{"tags":{"name":"Posto Shell","amenity":"fuel"},"name":"Posto Shell","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Phoenix":{"tags":{"name":"Phoenix","amenity":"fuel"},"name":"Phoenix","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Ipiranga":{"tags":{"name":"Ipiranga","amenity":"fuel"},"name":"Ipiranga","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/OKKO":{"tags":{"name":"OKKO","amenity":"fuel"},"name":"OKKO","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ОККО":{"tags":{"name":"ОККО","amenity":"fuel"},"name":"ОККО","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/บางจาก":{"tags":{"name":"บางจาก","amenity":"fuel"},"name":"บางจาก","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/QuikTrip":{"tags":{"name":"QuikTrip","amenity":"fuel"},"name":"QuikTrip","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Posto BR":{"tags":{"name":"Posto BR","amenity":"fuel"},"name":"Posto BR","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ป ต ท":{"tags":{"name":"ป ต ท","amenity":"fuel"},"name":"ป ต ท","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ปตท":{"tags":{"name":"ปตท","amenity":"fuel"},"name":"ปตท","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ANP":{"tags":{"name":"ANP","amenity":"fuel"},"name":"ANP","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Kum & Go":{"tags":{"name":"Kum & Go","amenity":"fuel"},"name":"Kum & Go","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petrolimex":{"tags":{"name":"Petrolimex","amenity":"fuel"},"name":"Petrolimex","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Sokimex":{"tags":{"name":"Sokimex","amenity":"fuel"},"name":"Sokimex","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Tela":{"tags":{"name":"Tela","amenity":"fuel"},"name":"Tela","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Posto":{"tags":{"name":"Posto","amenity":"fuel"},"name":"Posto","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Укрнафта":{"tags":{"name":"Укрнафта","amenity":"fuel"},"name":"Укрнафта","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Татнефтепродукт":{"tags":{"name":"Татнефтепродукт","amenity":"fuel"},"name":"Татнефтепродукт","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Afriquia":{"tags":{"name":"Afriquia","amenity":"fuel"},"name":"Afriquia","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Murphy USA":{"tags":{"name":"Murphy USA","amenity":"fuel"},"name":"Murphy USA","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/昭和シェル (Showa-shell)":{"tags":{"name":"昭和シェル (Showa-shell)","amenity":"fuel"},"name":"昭和シェル (Showa-shell)","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/エネオス":{"tags":{"name":"エネオス","amenity":"fuel"},"name":"エネオス","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/CNG":{"tags":{"name":"CNG","amenity":"fuel"},"name":"CNG","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/pub/Kings Arms":{"tags":{"name":"Kings Arms","amenity":"pub"},"name":"Kings Arms","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Ship":{"tags":{"name":"The Ship","amenity":"pub"},"name":"The Ship","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The White Horse":{"tags":{"name":"The White Horse","amenity":"pub"},"name":"The White Horse","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The White Hart":{"tags":{"name":"The White Hart","amenity":"pub"},"name":"The White Hart","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/Royal Oak":{"tags":{"name":"Royal Oak","amenity":"pub"},"name":"Royal Oak","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Red Lion":{"tags":{"name":"The Red Lion","amenity":"pub"},"name":"The Red Lion","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Kings Arms":{"tags":{"name":"The Kings Arms","amenity":"pub"},"name":"The Kings Arms","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Star":{"tags":{"name":"The Star","amenity":"pub"},"name":"The Star","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Anchor":{"tags":{"name":"The Anchor","amenity":"pub"},"name":"The Anchor","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Cross Keys":{"tags":{"name":"The Cross Keys","amenity":"pub"},"name":"The Cross Keys","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Wheatsheaf":{"tags":{"name":"The Wheatsheaf","amenity":"pub"},"name":"The Wheatsheaf","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Crown Inn":{"tags":{"name":"The Crown Inn","amenity":"pub"},"name":"The Crown Inn","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Kings Head":{"tags":{"name":"The Kings Head","amenity":"pub"},"name":"The Kings Head","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Castle":{"tags":{"name":"The Castle","amenity":"pub"},"name":"The Castle","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Railway":{"tags":{"name":"The Railway","amenity":"pub"},"name":"The Railway","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The White Lion":{"tags":{"name":"The White Lion","amenity":"pub"},"name":"The White Lion","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Bell":{"tags":{"name":"The Bell","amenity":"pub"},"name":"The Bell","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Bull":{"tags":{"name":"The Bull","amenity":"pub"},"name":"The Bull","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Plough":{"tags":{"name":"The Plough","amenity":"pub"},"name":"The Plough","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The George":{"tags":{"name":"The George","amenity":"pub"},"name":"The George","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Royal Oak":{"tags":{"name":"The Royal Oak","amenity":"pub"},"name":"The Royal Oak","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Fox":{"tags":{"name":"The Fox","amenity":"pub"},"name":"The Fox","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/Prince of Wales":{"tags":{"name":"Prince of Wales","amenity":"pub"},"name":"Prince of Wales","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Rising Sun":{"tags":{"name":"The Rising Sun","amenity":"pub"},"name":"The Rising Sun","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Prince of Wales":{"tags":{"name":"The Prince of Wales","amenity":"pub"},"name":"The Prince of Wales","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Crown":{"tags":{"name":"The Crown","amenity":"pub"},"name":"The Crown","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Chequers":{"tags":{"name":"The Chequers","amenity":"pub"},"name":"The Chequers","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Swan":{"tags":{"name":"The Swan","amenity":"pub"},"name":"The Swan","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/Rose and Crown":{"tags":{"name":"Rose and Crown","amenity":"pub"},"name":"Rose and Crown","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Victoria":{"tags":{"name":"The Victoria","amenity":"pub"},"name":"The Victoria","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/New Inn":{"tags":{"name":"New Inn","amenity":"pub"},"name":"New Inn","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/Royal Hotel":{"tags":{"name":"Royal Hotel","amenity":"pub"},"name":"Royal Hotel","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/Red Lion":{"tags":{"name":"Red Lion","amenity":"pub"},"name":"Red Lion","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/Cross Keys":{"tags":{"name":"Cross Keys","amenity":"pub"},"name":"Cross Keys","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Greyhound":{"tags":{"name":"The Greyhound","amenity":"pub"},"name":"The Greyhound","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Black Horse":{"tags":{"name":"The Black Horse","amenity":"pub"},"name":"The Black Horse","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The New Inn":{"tags":{"name":"The New Inn","amenity":"pub"},"name":"The New Inn","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/Kings Head":{"tags":{"name":"Kings Head","amenity":"pub"},"name":"Kings Head","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Albion":{"tags":{"name":"The Albion","amenity":"pub"},"name":"The Albion","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Angel":{"tags":{"name":"The Angel","amenity":"pub"},"name":"The Angel","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Queens Head":{"tags":{"name":"The Queens Head","amenity":"pub"},"name":"The Queens Head","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/The Ship Inn":{"tags":{"name":"The Ship Inn","amenity":"pub"},"name":"The Ship Inn","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/Rose & Crown":{"tags":{"name":"Rose & Crown","amenity":"pub"},"name":"Rose & Crown","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/Queens Head":{"tags":{"name":"Queens Head","amenity":"pub"},"name":"Queens Head","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/pub/Irish Pub":{"tags":{"name":"Irish Pub","amenity":"pub"},"name":"Irish Pub","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/fast_food/Quick":{"tags":{"name":"Quick","amenity":"fast_food"},"name":"Quick","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/McDonald's":{"tags":{"name":"McDonald's","cuisine":"burger","amenity":"fast_food"},"name":"McDonald's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Subway":{"tags":{"name":"Subway","cuisine":"sandwich","amenity":"fast_food"},"name":"Subway","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Burger King":{"tags":{"name":"Burger King","cuisine":"burger","amenity":"fast_food"},"name":"Burger King","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Ali Baba":{"tags":{"name":"Ali Baba","amenity":"fast_food"},"name":"Ali Baba","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Hungry Jacks":{"tags":{"name":"Hungry Jacks","cuisine":"burger","amenity":"fast_food"},"name":"Hungry Jacks","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Red Rooster":{"tags":{"name":"Red Rooster","amenity":"fast_food"},"name":"Red Rooster","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/KFC":{"tags":{"name":"KFC","cuisine":"chicken","amenity":"fast_food"},"name":"KFC","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Domino's Pizza":{"tags":{"name":"Domino's Pizza","cuisine":"pizza","amenity":"fast_food"},"name":"Domino's Pizza","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Chowking":{"tags":{"name":"Chowking","amenity":"fast_food"},"name":"Chowking","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Jollibee":{"tags":{"name":"Jollibee","amenity":"fast_food"},"name":"Jollibee","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Hesburger":{"tags":{"name":"Hesburger","amenity":"fast_food"},"name":"Hesburger","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/肯德基":{"tags":{"name":"肯德基","amenity":"fast_food"},"name":"肯德基","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Wendy's":{"tags":{"name":"Wendy's","cuisine":"burger","amenity":"fast_food"},"name":"Wendy's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Tim Hortons":{"tags":{"name":"Tim Hortons","amenity":"fast_food"},"name":"Tim Hortons","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Steers":{"tags":{"name":"Steers","amenity":"fast_food"},"name":"Steers","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Hardee's":{"tags":{"name":"Hardee's","cuisine":"burger","amenity":"fast_food"},"name":"Hardee's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Arby's":{"tags":{"name":"Arby's","amenity":"fast_food"},"name":"Arby's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/A&W":{"tags":{"name":"A&W","amenity":"fast_food"},"name":"A&W","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Dairy Queen":{"tags":{"name":"Dairy Queen","amenity":"fast_food"},"name":"Dairy Queen","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Hallo Pizza":{"tags":{"name":"Hallo Pizza","amenity":"fast_food"},"name":"Hallo Pizza","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Fish & Chips":{"tags":{"name":"Fish & Chips","amenity":"fast_food"},"name":"Fish & Chips","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Harvey's":{"tags":{"name":"Harvey's","amenity":"fast_food"},"name":"Harvey's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/麥當勞":{"tags":{"name":"麥當勞","amenity":"fast_food"},"name":"麥當勞","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Pizza Pizza":{"tags":{"name":"Pizza Pizza","amenity":"fast_food"},"name":"Pizza Pizza","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Kotipizza":{"tags":{"name":"Kotipizza","amenity":"fast_food"},"name":"Kotipizza","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Jack in the Box":{"tags":{"name":"Jack in the Box","cuisine":"burger","amenity":"fast_food"},"name":"Jack in the Box","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Istanbul":{"tags":{"name":"Istanbul","amenity":"fast_food"},"name":"Istanbul","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Kochlöffel":{"tags":{"name":"Kochlöffel","amenity":"fast_food"},"name":"Kochlöffel","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Döner":{"tags":{"name":"Döner","amenity":"fast_food"},"name":"Döner","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Telepizza":{"tags":{"name":"Telepizza","amenity":"fast_food"},"name":"Telepizza","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Sibylla":{"tags":{"name":"Sibylla","amenity":"fast_food"},"name":"Sibylla","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Carl's Jr.":{"tags":{"name":"Carl's Jr.","cuisine":"burger","amenity":"fast_food"},"name":"Carl's Jr.","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Quiznos":{"tags":{"name":"Quiznos","cuisine":"sandwich","amenity":"fast_food"},"name":"Quiznos","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Wimpy":{"tags":{"name":"Wimpy","amenity":"fast_food"},"name":"Wimpy","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Sonic":{"tags":{"name":"Sonic","cuisine":"burger","amenity":"fast_food"},"name":"Sonic","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Taco Bell":{"tags":{"name":"Taco Bell","cuisine":"mexican","amenity":"fast_food"},"name":"Taco Bell","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Pizza Nova":{"tags":{"name":"Pizza Nova","amenity":"fast_food"},"name":"Pizza Nova","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Papa John's":{"tags":{"name":"Papa John's","cuisine":"pizza","amenity":"fast_food"},"name":"Papa John's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Nordsee":{"tags":{"name":"Nordsee","amenity":"fast_food"},"name":"Nordsee","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Mr. Sub":{"tags":{"name":"Mr. Sub","amenity":"fast_food"},"name":"Mr. Sub","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Макдоналдс":{"tags":{"name":"Макдоналдс","name:en":"McDonald's","amenity":"fast_food"},"name":"Макдоналдс","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Asia Imbiss":{"tags":{"name":"Asia Imbiss","amenity":"fast_food"},"name":"Asia Imbiss","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Chipotle":{"tags":{"name":"Chipotle","cuisine":"mexican","amenity":"fast_food"},"name":"Chipotle","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/マクドナルド":{"tags":{"name":"マクドナルド","name:en":"McDonald's","cuisine":"burger","amenity":"fast_food"},"name":"マクドナルド","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/In-N-Out Burger":{"tags":{"name":"In-N-Out Burger","amenity":"fast_food"},"name":"In-N-Out Burger","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Jimmy John's":{"tags":{"name":"Jimmy John's","amenity":"fast_food"},"name":"Jimmy John's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Jamba Juice":{"tags":{"name":"Jamba Juice","amenity":"fast_food"},"name":"Jamba Juice","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Робин Сдобин":{"tags":{"name":"Робин Сдобин","amenity":"fast_food"},"name":"Робин Сдобин","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Baskin Robbins":{"tags":{"name":"Baskin Robbins","amenity":"fast_food"},"name":"Baskin Robbins","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/ケンタッキーフライドチキン":{"tags":{"name":"ケンタッキーフライドチキン","name:en":"KFC","cuisine":"chicken","amenity":"fast_food"},"name":"ケンタッキーフライドチキン","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/吉野家":{"tags":{"name":"吉野家","amenity":"fast_food"},"name":"吉野家","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Taco Time":{"tags":{"name":"Taco Time","amenity":"fast_food"},"name":"Taco Time","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/松屋":{"tags":{"name":"松屋","name:en":"Matsuya","amenity":"fast_food"},"name":"松屋","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Little Caesars":{"tags":{"name":"Little Caesars","amenity":"fast_food"},"name":"Little Caesars","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/El Pollo Loco":{"tags":{"name":"El Pollo Loco","amenity":"fast_food"},"name":"El Pollo Loco","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Del Taco":{"tags":{"name":"Del Taco","amenity":"fast_food"},"name":"Del Taco","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/White Castle":{"tags":{"name":"White Castle","amenity":"fast_food"},"name":"White Castle","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Boston Market":{"tags":{"name":"Boston Market","amenity":"fast_food"},"name":"Boston Market","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Chick-fil-A":{"tags":{"name":"Chick-fil-A","cuisine":"chicken","amenity":"fast_food"},"name":"Chick-fil-A","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Panda Express":{"tags":{"name":"Panda Express","cuisine":"chinese","amenity":"fast_food"},"name":"Panda Express","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Whataburger":{"tags":{"name":"Whataburger","amenity":"fast_food"},"name":"Whataburger","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Taco John's":{"tags":{"name":"Taco John's","amenity":"fast_food"},"name":"Taco John's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Теремок":{"tags":{"name":"Теремок","amenity":"fast_food"},"name":"Теремок","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Culver's":{"tags":{"name":"Culver's","amenity":"fast_food"},"name":"Culver's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Five Guys":{"tags":{"name":"Five Guys","amenity":"fast_food"},"name":"Five Guys","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Church's Chicken":{"tags":{"name":"Church's Chicken","amenity":"fast_food"},"name":"Church's Chicken","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Popeye's":{"tags":{"name":"Popeye's","cuisine":"chicken","amenity":"fast_food"},"name":"Popeye's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Long John Silver's":{"tags":{"name":"Long John Silver's","amenity":"fast_food"},"name":"Long John Silver's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Pollo Campero":{"tags":{"name":"Pollo Campero","amenity":"fast_food"},"name":"Pollo Campero","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Zaxby's":{"tags":{"name":"Zaxby's","amenity":"fast_food"},"name":"Zaxby's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/すき家":{"tags":{"name":"すき家","name:en":"SUKIYA","amenity":"fast_food"},"name":"すき家","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/モスバーガー":{"tags":{"name":"モスバーガー","name:en":"MOS BURGER","amenity":"fast_food"},"name":"モスバーガー","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/Русский Аппетит":{"tags":{"name":"Русский Аппетит","amenity":"fast_food"},"name":"Русский Аппетит","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/fast_food/なか卯":{"tags":{"name":"なか卯","amenity":"fast_food"},"name":"なか卯","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking"],"suggestion":true},"amenity/restaurant/Pizza Hut":{"tags":{"name":"Pizza Hut","cuisine":"pizza","amenity":"restaurant"},"name":"Pizza Hut","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Little Chef":{"tags":{"name":"Little Chef","amenity":"restaurant"},"name":"Little Chef","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Adler":{"tags":{"name":"Adler","amenity":"restaurant"},"name":"Adler","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Zur Krone":{"tags":{"name":"Zur Krone","amenity":"restaurant"},"name":"Zur Krone","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Deutsches Haus":{"tags":{"name":"Deutsches Haus","amenity":"restaurant"},"name":"Deutsches Haus","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Krone":{"tags":{"name":"Krone","amenity":"restaurant"},"name":"Krone","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Akropolis":{"tags":{"name":"Akropolis","amenity":"restaurant"},"name":"Akropolis","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Schützenhaus":{"tags":{"name":"Schützenhaus","amenity":"restaurant"},"name":"Schützenhaus","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Kreuz":{"tags":{"name":"Kreuz","amenity":"restaurant"},"name":"Kreuz","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Waldschänke":{"tags":{"name":"Waldschänke","amenity":"restaurant"},"name":"Waldschänke","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/La Piazza":{"tags":{"name":"La Piazza","amenity":"restaurant"},"name":"La Piazza","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Lamm":{"tags":{"name":"Lamm","amenity":"restaurant"},"name":"Lamm","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Zur Sonne":{"tags":{"name":"Zur Sonne","amenity":"restaurant"},"name":"Zur Sonne","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Zur Linde":{"tags":{"name":"Zur Linde","amenity":"restaurant"},"name":"Zur Linde","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Poseidon":{"tags":{"name":"Poseidon","amenity":"restaurant"},"name":"Poseidon","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Shanghai":{"tags":{"name":"Shanghai","amenity":"restaurant"},"name":"Shanghai","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Red Lobster":{"tags":{"name":"Red Lobster","amenity":"restaurant"},"name":"Red Lobster","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Zum Löwen":{"tags":{"name":"Zum Löwen","amenity":"restaurant"},"name":"Zum Löwen","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Swiss Chalet":{"tags":{"name":"Swiss Chalet","amenity":"restaurant"},"name":"Swiss Chalet","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Olympia":{"tags":{"name":"Olympia","amenity":"restaurant"},"name":"Olympia","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Wagamama":{"tags":{"name":"Wagamama","amenity":"restaurant"},"name":"Wagamama","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Frankie & Benny's":{"tags":{"name":"Frankie & Benny's","amenity":"restaurant"},"name":"Frankie & Benny's","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Hooters":{"tags":{"name":"Hooters","amenity":"restaurant"},"name":"Hooters","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Sternen":{"tags":{"name":"Sternen","amenity":"restaurant"},"name":"Sternen","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Hirschen":{"tags":{"name":"Hirschen","amenity":"restaurant"},"name":"Hirschen","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Denny's":{"tags":{"name":"Denny's","amenity":"restaurant"},"name":"Denny's","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Athen":{"tags":{"name":"Athen","amenity":"restaurant"},"name":"Athen","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Sonne":{"tags":{"name":"Sonne","amenity":"restaurant"},"name":"Sonne","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Hirsch":{"tags":{"name":"Hirsch","amenity":"restaurant"},"name":"Hirsch","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Ratskeller":{"tags":{"name":"Ratskeller","amenity":"restaurant"},"name":"Ratskeller","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/La Cantina":{"tags":{"name":"La Cantina","amenity":"restaurant"},"name":"La Cantina","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Gasthaus Krone":{"tags":{"name":"Gasthaus Krone","amenity":"restaurant"},"name":"Gasthaus Krone","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/El Greco":{"tags":{"name":"El Greco","amenity":"restaurant"},"name":"El Greco","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Gasthof zur Post":{"tags":{"name":"Gasthof zur Post","amenity":"restaurant"},"name":"Gasthof zur Post","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Nando's":{"tags":{"name":"Nando's","amenity":"restaurant"},"name":"Nando's","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Löwen":{"tags":{"name":"Löwen","amenity":"restaurant"},"name":"Löwen","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/La Pataterie":{"tags":{"name":"La Pataterie","amenity":"restaurant"},"name":"La Pataterie","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Bella Napoli":{"tags":{"name":"Bella Napoli","amenity":"restaurant"},"name":"Bella Napoli","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Pizza Express":{"tags":{"name":"Pizza Express","amenity":"restaurant"},"name":"Pizza Express","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Mandarin":{"tags":{"name":"Mandarin","amenity":"restaurant"},"name":"Mandarin","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Hong Kong":{"tags":{"name":"Hong Kong","amenity":"restaurant"},"name":"Hong Kong","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Zizzi":{"tags":{"name":"Zizzi","amenity":"restaurant"},"name":"Zizzi","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Cracker Barrel":{"tags":{"name":"Cracker Barrel","amenity":"restaurant"},"name":"Cracker Barrel","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Rhodos":{"tags":{"name":"Rhodos","amenity":"restaurant"},"name":"Rhodos","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Lindenhof":{"tags":{"name":"Lindenhof","amenity":"restaurant"},"name":"Lindenhof","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Milano":{"tags":{"name":"Milano","amenity":"restaurant"},"name":"Milano","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Dolce Vita":{"tags":{"name":"Dolce Vita","amenity":"restaurant"},"name":"Dolce Vita","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Kirchenwirt":{"tags":{"name":"Kirchenwirt","amenity":"restaurant"},"name":"Kirchenwirt","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Kantine":{"tags":{"name":"Kantine","amenity":"restaurant"},"name":"Kantine","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Ochsen":{"tags":{"name":"Ochsen","amenity":"restaurant"},"name":"Ochsen","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Spur":{"tags":{"name":"Spur","amenity":"restaurant"},"name":"Spur","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Mykonos":{"tags":{"name":"Mykonos","amenity":"restaurant"},"name":"Mykonos","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Lotus":{"tags":{"name":"Lotus","amenity":"restaurant"},"name":"Lotus","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Applebee's":{"tags":{"name":"Applebee's","amenity":"restaurant"},"name":"Applebee's","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Flunch":{"tags":{"name":"Flunch","amenity":"restaurant"},"name":"Flunch","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Zur Post":{"tags":{"name":"Zur Post","amenity":"restaurant"},"name":"Zur Post","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/China Town":{"tags":{"name":"China Town","amenity":"restaurant"},"name":"China Town","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/La Dolce Vita":{"tags":{"name":"La Dolce Vita","amenity":"restaurant"},"name":"La Dolce Vita","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Waffle House":{"tags":{"name":"Waffle House","amenity":"restaurant"},"name":"Waffle House","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Delphi":{"tags":{"name":"Delphi","amenity":"restaurant"},"name":"Delphi","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Linde":{"tags":{"name":"Linde","amenity":"restaurant"},"name":"Linde","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Outback Steakhouse":{"tags":{"name":"Outback Steakhouse","amenity":"restaurant"},"name":"Outback Steakhouse","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Dionysos":{"tags":{"name":"Dionysos","amenity":"restaurant"},"name":"Dionysos","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Kelsey's":{"tags":{"name":"Kelsey's","amenity":"restaurant"},"name":"Kelsey's","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Boston Pizza":{"tags":{"name":"Boston Pizza","amenity":"restaurant"},"name":"Boston Pizza","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Bella Italia":{"tags":{"name":"Bella Italia","amenity":"restaurant"},"name":"Bella Italia","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Sizzler":{"tags":{"name":"Sizzler","amenity":"restaurant"},"name":"Sizzler","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Grüner Baum":{"tags":{"name":"Grüner Baum","amenity":"restaurant"},"name":"Grüner Baum","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Taj Mahal":{"tags":{"name":"Taj Mahal","amenity":"restaurant"},"name":"Taj Mahal","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Rössli":{"tags":{"name":"Rössli","amenity":"restaurant"},"name":"Rössli","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Traube":{"tags":{"name":"Traube","amenity":"restaurant"},"name":"Traube","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Adria":{"tags":{"name":"Adria","amenity":"restaurant"},"name":"Adria","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Red Robin":{"tags":{"name":"Red Robin","amenity":"restaurant"},"name":"Red Robin","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Roma":{"tags":{"name":"Roma","amenity":"restaurant"},"name":"Roma","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/San Marco":{"tags":{"name":"San Marco","amenity":"restaurant"},"name":"San Marco","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Hellas":{"tags":{"name":"Hellas","amenity":"restaurant"},"name":"Hellas","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/La Perla":{"tags":{"name":"La Perla","amenity":"restaurant"},"name":"La Perla","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Vips":{"tags":{"name":"Vips","amenity":"restaurant"},"name":"Vips","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Panera Bread":{"tags":{"name":"Panera Bread","amenity":"restaurant"},"name":"Panera Bread","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Da Vinci":{"tags":{"name":"Da Vinci","amenity":"restaurant"},"name":"Da Vinci","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Hippopotamus":{"tags":{"name":"Hippopotamus","amenity":"restaurant"},"name":"Hippopotamus","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Prezzo":{"tags":{"name":"Prezzo","amenity":"restaurant"},"name":"Prezzo","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Courtepaille":{"tags":{"name":"Courtepaille","amenity":"restaurant"},"name":"Courtepaille","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Hard Rock Cafe":{"tags":{"name":"Hard Rock Cafe","amenity":"restaurant"},"name":"Hard Rock Cafe","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Panorama":{"tags":{"name":"Panorama","amenity":"restaurant"},"name":"Panorama","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/デニーズ":{"tags":{"name":"デニーズ","amenity":"restaurant"},"name":"デニーズ","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Sportheim":{"tags":{"name":"Sportheim","amenity":"restaurant"},"name":"Sportheim","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/餃子の王将":{"tags":{"name":"餃子の王将","amenity":"restaurant"},"name":"餃子の王将","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Bären":{"tags":{"name":"Bären","amenity":"restaurant"},"name":"Bären","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Alte Post":{"tags":{"name":"Alte Post","amenity":"restaurant"},"name":"Alte Post","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Pizzeria Roma":{"tags":{"name":"Pizzeria Roma","amenity":"restaurant"},"name":"Pizzeria Roma","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/China Garden":{"tags":{"name":"China Garden","amenity":"restaurant"},"name":"China Garden","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Vapiano":{"tags":{"name":"Vapiano","amenity":"restaurant"},"name":"Vapiano","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Mamma Mia":{"tags":{"name":"Mamma Mia","amenity":"restaurant"},"name":"Mamma Mia","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Schwarzer Adler":{"tags":{"name":"Schwarzer Adler","amenity":"restaurant"},"name":"Schwarzer Adler","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/IHOP":{"tags":{"name":"IHOP","amenity":"restaurant"},"name":"IHOP","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Chili's":{"tags":{"name":"Chili's","amenity":"restaurant"},"name":"Chili's","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Asia":{"tags":{"name":"Asia","amenity":"restaurant"},"name":"Asia","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Olive Garden":{"tags":{"name":"Olive Garden","amenity":"restaurant"},"name":"Olive Garden","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/TGI Friday's":{"tags":{"name":"TGI Friday's","amenity":"restaurant"},"name":"TGI Friday's","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Friendly's":{"tags":{"name":"Friendly's","amenity":"restaurant"},"name":"Friendly's","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Buffalo Grill":{"tags":{"name":"Buffalo Grill","amenity":"restaurant"},"name":"Buffalo Grill","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Texas Roadhouse":{"tags":{"name":"Texas Roadhouse","amenity":"restaurant"},"name":"Texas Roadhouse","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/ガスト":{"tags":{"name":"ガスト","name:en":"Gusto","amenity":"restaurant"},"name":"ガスト","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Sakura":{"tags":{"name":"Sakura","amenity":"restaurant"},"name":"Sakura","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Mensa":{"tags":{"name":"Mensa","amenity":"restaurant"},"name":"Mensa","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/The Keg":{"tags":{"name":"The Keg","amenity":"restaurant"},"name":"The Keg","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/サイゼリヤ":{"tags":{"name":"サイゼリヤ","amenity":"restaurant"},"name":"サイゼリヤ","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/La Strada":{"tags":{"name":"La Strada","amenity":"restaurant"},"name":"La Strada","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Village Inn":{"tags":{"name":"Village Inn","amenity":"restaurant"},"name":"Village Inn","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Buffalo Wild Wings":{"tags":{"name":"Buffalo Wild Wings","amenity":"restaurant"},"name":"Buffalo Wild Wings","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Peking":{"tags":{"name":"Peking","amenity":"restaurant"},"name":"Peking","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Round Table Pizza":{"tags":{"name":"Round Table Pizza","amenity":"restaurant"},"name":"Round Table Pizza","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/California Pizza Kitchen":{"tags":{"name":"California Pizza Kitchen","amenity":"restaurant"},"name":"California Pizza Kitchen","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Якитория":{"tags":{"name":"Якитория","amenity":"restaurant"},"name":"Якитория","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Golden Corral":{"tags":{"name":"Golden Corral","amenity":"restaurant"},"name":"Golden Corral","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Perkins":{"tags":{"name":"Perkins","amenity":"restaurant"},"name":"Perkins","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Ruby Tuesday":{"tags":{"name":"Ruby Tuesday","amenity":"restaurant"},"name":"Ruby Tuesday","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Shari's":{"tags":{"name":"Shari's","amenity":"restaurant"},"name":"Shari's","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Bob Evans":{"tags":{"name":"Bob Evans","amenity":"restaurant"},"name":"Bob Evans","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/바다횟집 (Bada Fish Restaurant)":{"tags":{"name":"바다횟집 (Bada Fish Restaurant)","amenity":"restaurant"},"name":"바다횟집 (Bada Fish Restaurant)","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Mang Inasal":{"tags":{"name":"Mang Inasal","amenity":"restaurant"},"name":"Mang Inasal","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Евразия":{"tags":{"name":"Евразия","amenity":"restaurant"},"name":"Евразия","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/ジョナサン":{"tags":{"name":"ジョナサン","amenity":"restaurant"},"name":"ジョナサン","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/restaurant/Longhorn Steakhouse":{"tags":{"name":"Longhorn Steakhouse","amenity":"restaurant"},"name":"Longhorn Steakhouse","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking"],"suggestion":true},"amenity/bank/Chase":{"tags":{"name":"Chase","amenity":"bank"},"name":"Chase","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Commonwealth Bank":{"tags":{"name":"Commonwealth Bank","amenity":"bank"},"name":"Commonwealth Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Citibank":{"tags":{"name":"Citibank","amenity":"bank"},"name":"Citibank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/HSBC":{"tags":{"name":"HSBC","amenity":"bank"},"name":"HSBC","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Barclays":{"tags":{"name":"Barclays","amenity":"bank"},"name":"Barclays","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Westpac":{"tags":{"name":"Westpac","amenity":"bank"},"name":"Westpac","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/NAB":{"tags":{"name":"NAB","amenity":"bank"},"name":"NAB","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ANZ":{"tags":{"name":"ANZ","amenity":"bank"},"name":"ANZ","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Lloyds Bank":{"tags":{"name":"Lloyds Bank","amenity":"bank"},"name":"Lloyds Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Landbank":{"tags":{"name":"Landbank","amenity":"bank"},"name":"Landbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Sparkasse":{"tags":{"name":"Sparkasse","amenity":"bank"},"name":"Sparkasse","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/UCPB":{"tags":{"name":"UCPB","amenity":"bank"},"name":"UCPB","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/PNB":{"tags":{"name":"PNB","amenity":"bank"},"name":"PNB","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Metrobank":{"tags":{"name":"Metrobank","amenity":"bank"},"name":"Metrobank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BDO":{"tags":{"name":"BDO","amenity":"bank"},"name":"BDO","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Volksbank":{"tags":{"name":"Volksbank","amenity":"bank"},"name":"Volksbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BPI":{"tags":{"name":"BPI","amenity":"bank"},"name":"BPI","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Postbank":{"tags":{"name":"Postbank","amenity":"bank"},"name":"Postbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/NatWest":{"tags":{"name":"NatWest","amenity":"bank"},"name":"NatWest","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Raiffeisenbank":{"tags":{"name":"Raiffeisenbank","amenity":"bank"},"name":"Raiffeisenbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Yorkshire Bank":{"tags":{"name":"Yorkshire Bank","amenity":"bank"},"name":"Yorkshire Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ABSA":{"tags":{"name":"ABSA","amenity":"bank"},"name":"ABSA","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Standard Bank":{"tags":{"name":"Standard Bank","amenity":"bank"},"name":"Standard Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/FNB":{"tags":{"name":"FNB","amenity":"bank"},"name":"FNB","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Deutsche Bank":{"tags":{"name":"Deutsche Bank","amenity":"bank"},"name":"Deutsche Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/SEB":{"tags":{"name":"SEB","amenity":"bank"},"name":"SEB","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Commerzbank":{"tags":{"name":"Commerzbank","amenity":"bank"},"name":"Commerzbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Targobank":{"tags":{"name":"Targobank","amenity":"bank"},"name":"Targobank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ABN AMRO":{"tags":{"name":"ABN AMRO","amenity":"bank"},"name":"ABN AMRO","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Handelsbanken":{"tags":{"name":"Handelsbanken","amenity":"bank"},"name":"Handelsbanken","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Swedbank":{"tags":{"name":"Swedbank","amenity":"bank"},"name":"Swedbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Kreissparkasse":{"tags":{"name":"Kreissparkasse","amenity":"bank"},"name":"Kreissparkasse","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/UniCredit Bank":{"tags":{"name":"UniCredit Bank","amenity":"bank"},"name":"UniCredit Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Monte dei Paschi di Siena":{"tags":{"name":"Monte dei Paschi di Siena","amenity":"bank"},"name":"Monte dei Paschi di Siena","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caja Rural":{"tags":{"name":"Caja Rural","amenity":"bank"},"name":"Caja Rural","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Dresdner Bank":{"tags":{"name":"Dresdner Bank","amenity":"bank"},"name":"Dresdner Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Sparda-Bank":{"tags":{"name":"Sparda-Bank","amenity":"bank"},"name":"Sparda-Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/VÚB":{"tags":{"name":"VÚB","amenity":"bank"},"name":"VÚB","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Slovenská sporiteľňa":{"tags":{"name":"Slovenská sporiteľňa","amenity":"bank"},"name":"Slovenská sporiteľňa","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of Montreal":{"tags":{"name":"Bank of Montreal","amenity":"bank"},"name":"Bank of Montreal","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/KBC":{"tags":{"name":"KBC","amenity":"bank"},"name":"KBC","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Royal Bank of Scotland":{"tags":{"name":"Royal Bank of Scotland","amenity":"bank"},"name":"Royal Bank of Scotland","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/TSB":{"tags":{"name":"TSB","amenity":"bank"},"name":"TSB","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/US Bank":{"tags":{"name":"US Bank","amenity":"bank"},"name":"US Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/HypoVereinsbank":{"tags":{"name":"HypoVereinsbank","amenity":"bank"},"name":"HypoVereinsbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank Austria":{"tags":{"name":"Bank Austria","amenity":"bank"},"name":"Bank Austria","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ING":{"tags":{"name":"ING","amenity":"bank"},"name":"ING","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Erste Bank":{"tags":{"name":"Erste Bank","amenity":"bank"},"name":"Erste Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CIBC":{"tags":{"name":"CIBC","amenity":"bank"},"name":"CIBC","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Scotiabank":{"tags":{"name":"Scotiabank","amenity":"bank"},"name":"Scotiabank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caisse d'Épargne":{"tags":{"name":"Caisse d'Épargne","amenity":"bank"},"name":"Caisse d'Épargne","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Santander":{"tags":{"name":"Santander","amenity":"bank"},"name":"Santander","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of Scotland":{"tags":{"name":"Bank of Scotland","amenity":"bank"},"name":"Bank of Scotland","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/TD Canada Trust":{"tags":{"name":"TD Canada Trust","amenity":"bank"},"name":"TD Canada Trust","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BMO":{"tags":{"name":"BMO","amenity":"bank"},"name":"BMO","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Danske Bank":{"tags":{"name":"Danske Bank","amenity":"bank"},"name":"Danske Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/OTP":{"tags":{"name":"OTP","amenity":"bank"},"name":"OTP","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Crédit Agricole":{"tags":{"name":"Crédit Agricole","amenity":"bank"},"name":"Crédit Agricole","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/LCL":{"tags":{"name":"LCL","amenity":"bank"},"name":"LCL","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/VR-Bank":{"tags":{"name":"VR-Bank","amenity":"bank"},"name":"VR-Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ČSOB":{"tags":{"name":"ČSOB","amenity":"bank"},"name":"ČSOB","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Česká spořitelna":{"tags":{"name":"Česká spořitelna","amenity":"bank"},"name":"Česká spořitelna","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BNP":{"tags":{"name":"BNP","amenity":"bank"},"name":"BNP","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Royal Bank":{"tags":{"name":"Royal Bank","amenity":"bank"},"name":"Royal Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Nationwide":{"tags":{"name":"Nationwide","amenity":"bank"},"name":"Nationwide","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Halifax":{"tags":{"name":"Halifax","amenity":"bank"},"name":"Halifax","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BAWAG PSK":{"tags":{"name":"BAWAG PSK","amenity":"bank"},"name":"BAWAG PSK","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/National Bank":{"tags":{"name":"National Bank","amenity":"bank"},"name":"National Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Nedbank":{"tags":{"name":"Nedbank","amenity":"bank"},"name":"Nedbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/First National Bank":{"tags":{"name":"First National Bank","amenity":"bank"},"name":"First National Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Nordea":{"tags":{"name":"Nordea","amenity":"bank"},"name":"Nordea","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Rabobank":{"tags":{"name":"Rabobank","amenity":"bank"},"name":"Rabobank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Sparkasse KölnBonn":{"tags":{"name":"Sparkasse KölnBonn","amenity":"bank"},"name":"Sparkasse KölnBonn","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Tatra banka":{"tags":{"name":"Tatra banka","amenity":"bank"},"name":"Tatra banka","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Berliner Sparkasse":{"tags":{"name":"Berliner Sparkasse","amenity":"bank"},"name":"Berliner Sparkasse","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Berliner Volksbank":{"tags":{"name":"Berliner Volksbank","amenity":"bank"},"name":"Berliner Volksbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Wells Fargo":{"tags":{"name":"Wells Fargo","amenity":"bank"},"name":"Wells Fargo","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Credit Suisse":{"tags":{"name":"Credit Suisse","amenity":"bank"},"name":"Credit Suisse","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Société Générale":{"tags":{"name":"Société Générale","amenity":"bank"},"name":"Société Générale","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Osuuspankki":{"tags":{"name":"Osuuspankki","amenity":"bank"},"name":"Osuuspankki","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Sparkasse Aachen":{"tags":{"name":"Sparkasse Aachen","amenity":"bank"},"name":"Sparkasse Aachen","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Hamburger Sparkasse":{"tags":{"name":"Hamburger Sparkasse","amenity":"bank"},"name":"Hamburger Sparkasse","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Cassa di Risparmio del Veneto":{"tags":{"name":"Cassa di Risparmio del Veneto","amenity":"bank"},"name":"Cassa di Risparmio del Veneto","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BNP Paribas":{"tags":{"name":"BNP Paribas","amenity":"bank"},"name":"BNP Paribas","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banque Populaire":{"tags":{"name":"Banque Populaire","amenity":"bank"},"name":"Banque Populaire","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BNP Paribas Fortis":{"tags":{"name":"BNP Paribas Fortis","amenity":"bank"},"name":"BNP Paribas Fortis","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Popular":{"tags":{"name":"Banco Popular","amenity":"bank"},"name":"Banco Popular","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bancaja":{"tags":{"name":"Bancaja","amenity":"bank"},"name":"Bancaja","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banesto":{"tags":{"name":"Banesto","amenity":"bank"},"name":"Banesto","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/La Caixa":{"tags":{"name":"La Caixa","amenity":"bank"},"name":"La Caixa","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Santander Consumer Bank":{"tags":{"name":"Santander Consumer Bank","amenity":"bank"},"name":"Santander Consumer Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BRD":{"tags":{"name":"BRD","amenity":"bank"},"name":"BRD","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BCR":{"tags":{"name":"BCR","amenity":"bank"},"name":"BCR","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banca Transilvania":{"tags":{"name":"Banca Transilvania","amenity":"bank"},"name":"Banca Transilvania","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BW-Bank":{"tags":{"name":"BW-Bank","amenity":"bank"},"name":"BW-Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Komerční banka":{"tags":{"name":"Komerční banka","amenity":"bank"},"name":"Komerční banka","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Pastor":{"tags":{"name":"Banco Pastor","amenity":"bank"},"name":"Banco Pastor","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Stadtsparkasse":{"tags":{"name":"Stadtsparkasse","amenity":"bank"},"name":"Stadtsparkasse","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Ulster Bank":{"tags":{"name":"Ulster Bank","amenity":"bank"},"name":"Ulster Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Sberbank":{"tags":{"name":"Sberbank","amenity":"bank"},"name":"Sberbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CIC":{"tags":{"name":"CIC","amenity":"bank"},"name":"CIC","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bancpost":{"tags":{"name":"Bancpost","amenity":"bank"},"name":"Bancpost","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caja Madrid":{"tags":{"name":"Caja Madrid","amenity":"bank"},"name":"Caja Madrid","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Maybank":{"tags":{"name":"Maybank","amenity":"bank"},"name":"Maybank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/中国银行":{"tags":{"name":"中国银行","amenity":"bank"},"name":"中国银行","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Unicredit Banca":{"tags":{"name":"Unicredit Banca","amenity":"bank"},"name":"Unicredit Banca","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Crédit Mutuel":{"tags":{"name":"Crédit Mutuel","amenity":"bank"},"name":"Crédit Mutuel","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BBVA":{"tags":{"name":"BBVA","amenity":"bank"},"name":"BBVA","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Intesa San Paolo":{"tags":{"name":"Intesa San Paolo","amenity":"bank"},"name":"Intesa San Paolo","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/TD Bank":{"tags":{"name":"TD Bank","amenity":"bank"},"name":"TD Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Belfius":{"tags":{"name":"Belfius","amenity":"bank"},"name":"Belfius","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of America":{"tags":{"name":"Bank of America","amenity":"bank"},"name":"Bank of America","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/RBC":{"tags":{"name":"RBC","amenity":"bank"},"name":"RBC","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Alpha Bank":{"tags":{"name":"Alpha Bank","amenity":"bank"},"name":"Alpha Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Сбербанк":{"tags":{"name":"Сбербанк","amenity":"bank"},"name":"Сбербанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Россельхозбанк":{"tags":{"name":"Россельхозбанк","amenity":"bank"},"name":"Россельхозбанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Crédit du Nord":{"tags":{"name":"Crédit du Nord","amenity":"bank"},"name":"Crédit du Nord","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BancoEstado":{"tags":{"name":"BancoEstado","amenity":"bank"},"name":"BancoEstado","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Millennium Bank":{"tags":{"name":"Millennium Bank","amenity":"bank"},"name":"Millennium Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/State Bank of India":{"tags":{"name":"State Bank of India","amenity":"bank"},"name":"State Bank of India","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Беларусбанк":{"tags":{"name":"Беларусбанк","amenity":"bank"},"name":"Беларусбанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ING Bank Śląski":{"tags":{"name":"ING Bank Śląski","amenity":"bank"},"name":"ING Bank Śląski","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caixa Geral de Depósitos":{"tags":{"name":"Caixa Geral de Depósitos","amenity":"bank"},"name":"Caixa Geral de Depósitos","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Kreissparkasse Köln":{"tags":{"name":"Kreissparkasse Köln","amenity":"bank"},"name":"Kreissparkasse Köln","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco BCI":{"tags":{"name":"Banco BCI","amenity":"bank"},"name":"Banco BCI","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco de Chile":{"tags":{"name":"Banco de Chile","amenity":"bank"},"name":"Banco de Chile","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ВТБ24":{"tags":{"name":"ВТБ24","amenity":"bank"},"name":"ВТБ24","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/UBS":{"tags":{"name":"UBS","amenity":"bank"},"name":"UBS","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/PKO BP":{"tags":{"name":"PKO BP","amenity":"bank"},"name":"PKO BP","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Chinabank":{"tags":{"name":"Chinabank","amenity":"bank"},"name":"Chinabank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/PSBank":{"tags":{"name":"PSBank","amenity":"bank"},"name":"PSBank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Union Bank":{"tags":{"name":"Union Bank","amenity":"bank"},"name":"Union Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/China Bank":{"tags":{"name":"China Bank","amenity":"bank"},"name":"China Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/RCBC":{"tags":{"name":"RCBC","amenity":"bank"},"name":"RCBC","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Unicaja":{"tags":{"name":"Unicaja","amenity":"bank"},"name":"Unicaja","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BBK":{"tags":{"name":"BBK","amenity":"bank"},"name":"BBK","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Ibercaja":{"tags":{"name":"Ibercaja","amenity":"bank"},"name":"Ibercaja","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/RBS":{"tags":{"name":"RBS","amenity":"bank"},"name":"RBS","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Commercial Bank of Ceylon PLC":{"tags":{"name":"Commercial Bank of Ceylon PLC","amenity":"bank"},"name":"Commercial Bank of Ceylon PLC","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of Ireland":{"tags":{"name":"Bank of Ireland","amenity":"bank"},"name":"Bank of Ireland","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BNL":{"tags":{"name":"BNL","amenity":"bank"},"name":"BNL","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Santander":{"tags":{"name":"Banco Santander","amenity":"bank"},"name":"Banco Santander","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Itaú":{"tags":{"name":"Banco Itaú","amenity":"bank"},"name":"Banco Itaú","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/AIB":{"tags":{"name":"AIB","amenity":"bank"},"name":"AIB","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BZ WBK":{"tags":{"name":"BZ WBK","amenity":"bank"},"name":"BZ WBK","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco do Brasil":{"tags":{"name":"Banco do Brasil","amenity":"bank"},"name":"Banco do Brasil","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caixa Econômica Federal":{"tags":{"name":"Caixa Econômica Federal","amenity":"bank"},"name":"Caixa Econômica Federal","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Fifth Third Bank":{"tags":{"name":"Fifth Third Bank","amenity":"bank"},"name":"Fifth Third Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banca Popolare di Vicenza":{"tags":{"name":"Banca Popolare di Vicenza","amenity":"bank"},"name":"Banca Popolare di Vicenza","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Wachovia":{"tags":{"name":"Wachovia","amenity":"bank"},"name":"Wachovia","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/OLB":{"tags":{"name":"OLB","amenity":"bank"},"name":"OLB","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/みずほ銀行":{"tags":{"name":"みずほ銀行","amenity":"bank"},"name":"みずほ銀行","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BES":{"tags":{"name":"BES","amenity":"bank"},"name":"BES","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ICICI Bank":{"tags":{"name":"ICICI Bank","amenity":"bank"},"name":"ICICI Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/HDFC Bank":{"tags":{"name":"HDFC Bank","amenity":"bank"},"name":"HDFC Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/La Banque Postale":{"tags":{"name":"La Banque Postale","amenity":"bank"},"name":"La Banque Postale","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Pekao SA":{"tags":{"name":"Pekao SA","amenity":"bank"},"name":"Pekao SA","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Oberbank":{"tags":{"name":"Oberbank","amenity":"bank"},"name":"Oberbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bradesco":{"tags":{"name":"Bradesco","amenity":"bank"},"name":"Bradesco","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Oldenburgische Landesbank":{"tags":{"name":"Oldenburgische Landesbank","amenity":"bank"},"name":"Oldenburgische Landesbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bendigo Bank":{"tags":{"name":"Bendigo Bank","amenity":"bank"},"name":"Bendigo Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Argenta":{"tags":{"name":"Argenta","amenity":"bank"},"name":"Argenta","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/AXA":{"tags":{"name":"AXA","amenity":"bank"},"name":"AXA","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Axis Bank":{"tags":{"name":"Axis Bank","amenity":"bank"},"name":"Axis Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Nación":{"tags":{"name":"Banco Nación","amenity":"bank"},"name":"Banco Nación","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/GE Money Bank":{"tags":{"name":"GE Money Bank","amenity":"bank"},"name":"GE Money Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Альфа-Банк":{"tags":{"name":"Альфа-Банк","amenity":"bank"},"name":"Альфа-Банк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Белагропромбанк":{"tags":{"name":"Белагропромбанк","amenity":"bank"},"name":"Белагропромбанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caja Círculo":{"tags":{"name":"Caja Círculo","amenity":"bank"},"name":"Caja Círculo","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Galicia":{"tags":{"name":"Banco Galicia","amenity":"bank"},"name":"Banco Galicia","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Eurobank":{"tags":{"name":"Eurobank","amenity":"bank"},"name":"Eurobank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banca Intesa":{"tags":{"name":"Banca Intesa","amenity":"bank"},"name":"Banca Intesa","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Canara Bank":{"tags":{"name":"Canara Bank","amenity":"bank"},"name":"Canara Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Cajamar":{"tags":{"name":"Cajamar","amenity":"bank"},"name":"Cajamar","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banamex":{"tags":{"name":"Banamex","amenity":"bank"},"name":"Banamex","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Crédit Mutuel de Bretagne":{"tags":{"name":"Crédit Mutuel de Bretagne","amenity":"bank"},"name":"Crédit Mutuel de Bretagne","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Davivienda":{"tags":{"name":"Davivienda","amenity":"bank"},"name":"Davivienda","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank Spółdzielczy":{"tags":{"name":"Bank Spółdzielczy","amenity":"bank"},"name":"Bank Spółdzielczy","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Credit Agricole":{"tags":{"name":"Credit Agricole","amenity":"bank"},"name":"Credit Agricole","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bankinter":{"tags":{"name":"Bankinter","amenity":"bank"},"name":"Bankinter","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banque Nationale":{"tags":{"name":"Banque Nationale","amenity":"bank"},"name":"Banque Nationale","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of the West":{"tags":{"name":"Bank of the West","amenity":"bank"},"name":"Bank of the West","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Key Bank":{"tags":{"name":"Key Bank","amenity":"bank"},"name":"Key Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Western Union":{"tags":{"name":"Western Union","amenity":"bank"},"name":"Western Union","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Citizens Bank":{"tags":{"name":"Citizens Bank","amenity":"bank"},"name":"Citizens Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ПриватБанк":{"tags":{"name":"ПриватБанк","amenity":"bank"},"name":"ПриватБанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Security Bank":{"tags":{"name":"Security Bank","amenity":"bank"},"name":"Security Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Millenium":{"tags":{"name":"Millenium","amenity":"bank"},"name":"Millenium","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bankia":{"tags":{"name":"Bankia","amenity":"bank"},"name":"Bankia","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/三菱東京UFJ銀行":{"tags":{"name":"三菱東京UFJ銀行","amenity":"bank"},"name":"三菱東京UFJ銀行","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caixa":{"tags":{"name":"Caixa","amenity":"bank"},"name":"Caixa","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco de Costa Rica":{"tags":{"name":"Banco de Costa Rica","amenity":"bank"},"name":"Banco de Costa Rica","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/SunTrust Bank":{"tags":{"name":"SunTrust Bank","amenity":"bank"},"name":"SunTrust Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Itaú":{"tags":{"name":"Itaú","amenity":"bank"},"name":"Itaú","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/PBZ":{"tags":{"name":"PBZ","amenity":"bank"},"name":"PBZ","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/中国工商银行":{"tags":{"name":"中国工商银行","amenity":"bank"},"name":"中国工商银行","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bancolombia":{"tags":{"name":"Bancolombia","amenity":"bank"},"name":"Bancolombia","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Райффайзен Банк Аваль":{"tags":{"name":"Райффайзен Банк Аваль","amenity":"bank"},"name":"Райффайзен Банк Аваль","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bancomer":{"tags":{"name":"Bancomer","amenity":"bank"},"name":"Bancomer","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banorte":{"tags":{"name":"Banorte","amenity":"bank"},"name":"Banorte","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Alior Bank":{"tags":{"name":"Alior Bank","amenity":"bank"},"name":"Alior Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BOC":{"tags":{"name":"BOC","amenity":"bank"},"name":"BOC","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Банк Москвы":{"tags":{"name":"Банк Москвы","amenity":"bank"},"name":"Банк Москвы","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ВТБ":{"tags":{"name":"ВТБ","amenity":"bank"},"name":"ВТБ","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Getin Bank":{"tags":{"name":"Getin Bank","amenity":"bank"},"name":"Getin Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caja Duero":{"tags":{"name":"Caja Duero","amenity":"bank"},"name":"Caja Duero","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Regions Bank":{"tags":{"name":"Regions Bank","amenity":"bank"},"name":"Regions Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Росбанк":{"tags":{"name":"Росбанк","amenity":"bank"},"name":"Росбанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Estado":{"tags":{"name":"Banco Estado","amenity":"bank"},"name":"Banco Estado","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BCI":{"tags":{"name":"BCI","amenity":"bank"},"name":"BCI","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/SunTrust":{"tags":{"name":"SunTrust","amenity":"bank"},"name":"SunTrust","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/PNC Bank":{"tags":{"name":"PNC Bank","amenity":"bank"},"name":"PNC Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/신한은행":{"tags":{"name":"신한은행","name:en":"Sinhan Bank","amenity":"bank"},"name":"신한은행","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/우리은행":{"tags":{"name":"우리은행","name:en":"Uri Bank","amenity":"bank"},"name":"우리은행","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/국민은행":{"tags":{"name":"국민은행","name:en":"Gungmin Bank","amenity":"bank"},"name":"국민은행","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/중소기업은행":{"tags":{"name":"중소기업은행","name:en":"Industrial Bank of Korea","amenity":"bank"},"name":"중소기업은행","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/광주은행":{"tags":{"name":"광주은행","name:en":"Gwangju Bank","amenity":"bank"},"name":"광주은행","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Газпромбанк":{"tags":{"name":"Газпромбанк","amenity":"bank"},"name":"Газпромбанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/M&T Bank":{"tags":{"name":"M&T Bank","amenity":"bank"},"name":"M&T Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caja de Burgos":{"tags":{"name":"Caja de Burgos","amenity":"bank"},"name":"Caja de Burgos","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Santander Totta":{"tags":{"name":"Santander Totta","amenity":"bank"},"name":"Santander Totta","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/УкрСиббанк":{"tags":{"name":"УкрСиббанк","amenity":"bank"},"name":"УкрСиббанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Ощадбанк":{"tags":{"name":"Ощадбанк","amenity":"bank"},"name":"Ощадбанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Уралсиб":{"tags":{"name":"Уралсиб","amenity":"bank"},"name":"Уралсиб","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/りそな銀行":{"tags":{"name":"りそな銀行","name:en":"Mizuho Bank","amenity":"bank"},"name":"りそな銀行","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Ecobank":{"tags":{"name":"Ecobank","amenity":"bank"},"name":"Ecobank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Cajero Automatico Bancared":{"tags":{"name":"Cajero Automatico Bancared","amenity":"bank"},"name":"Cajero Automatico Bancared","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Промсвязьбанк":{"tags":{"name":"Промсвязьбанк","amenity":"bank"},"name":"Промсвязьбанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/三井住友銀行":{"tags":{"name":"三井住友銀行","amenity":"bank"},"name":"三井住友銀行","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Provincia":{"tags":{"name":"Banco Provincia","amenity":"bank"},"name":"Banco Provincia","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BB&T":{"tags":{"name":"BB&T","amenity":"bank"},"name":"BB&T","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Возрождение":{"tags":{"name":"Возрождение","amenity":"bank"},"name":"Возрождение","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Capital One":{"tags":{"name":"Capital One","amenity":"bank"},"name":"Capital One","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/横浜銀行":{"tags":{"name":"横浜銀行","amenity":"bank"},"name":"横浜銀行","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank Mandiri":{"tags":{"name":"Bank Mandiri","amenity":"bank"},"name":"Bank Mandiri","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco de la Nación":{"tags":{"name":"Banco de la Nación","amenity":"bank"},"name":"Banco de la Nación","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco G&T Continental":{"tags":{"name":"Banco G&T Continental","amenity":"bank"},"name":"Banco G&T Continental","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Peoples Bank":{"tags":{"name":"Peoples Bank","amenity":"bank"},"name":"Peoples Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/工商银行":{"tags":{"name":"工商银行","amenity":"bank"},"name":"工商银行","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Совкомбанк":{"tags":{"name":"Совкомбанк","amenity":"bank"},"name":"Совкомбанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Provincial":{"tags":{"name":"Provincial","amenity":"bank"},"name":"Provincial","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco de Desarrollo Banrural":{"tags":{"name":"Banco de Desarrollo Banrural","amenity":"bank"},"name":"Banco de Desarrollo Banrural","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Bradesco":{"tags":{"name":"Banco Bradesco","amenity":"bank"},"name":"Banco Bradesco","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bicentenario":{"tags":{"name":"Bicentenario","amenity":"bank"},"name":"Bicentenario","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ლიბერთი ბანკი":{"tags":{"name":"ლიბერთი ბანკი","name:en":"Liberty Bank","amenity":"bank"},"name":"ლიბერთი ბანკი","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banesco":{"tags":{"name":"Banesco","amenity":"bank"},"name":"Banesco","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Mercantil":{"tags":{"name":"Mercantil","amenity":"bank"},"name":"Mercantil","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank BRI":{"tags":{"name":"Bank BRI","amenity":"bank"},"name":"Bank BRI","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Del Tesoro":{"tags":{"name":"Del Tesoro","amenity":"bank"},"name":"Del Tesoro","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/하나은행":{"tags":{"name":"하나은행","amenity":"bank"},"name":"하나은행","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CityCommerce Bank":{"tags":{"name":"CityCommerce Bank","amenity":"bank"},"name":"CityCommerce Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/De Venezuela":{"tags":{"name":"De Venezuela","amenity":"bank"},"name":"De Venezuela","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/car_rental/Europcar":{"tags":{"name":"Europcar","amenity":"car_rental"},"name":"Europcar","icon":"car","geometry":["point","area"],"fields":["operator"],"suggestion":true},"amenity/car_rental/Budget":{"tags":{"name":"Budget","amenity":"car_rental"},"name":"Budget","icon":"car","geometry":["point","area"],"fields":["operator"],"suggestion":true},"amenity/car_rental/Sixt":{"tags":{"name":"Sixt","amenity":"car_rental"},"name":"Sixt","icon":"car","geometry":["point","area"],"fields":["operator"],"suggestion":true},"amenity/car_rental/Avis":{"tags":{"name":"Avis","amenity":"car_rental"},"name":"Avis","icon":"car","geometry":["point","area"],"fields":["operator"],"suggestion":true},"amenity/car_rental/Hertz":{"tags":{"name":"Hertz","amenity":"car_rental"},"name":"Hertz","icon":"car","geometry":["point","area"],"fields":["operator"],"suggestion":true},"amenity/car_rental/Enterprise":{"tags":{"name":"Enterprise","amenity":"car_rental"},"name":"Enterprise","icon":"car","geometry":["point","area"],"fields":["operator"],"suggestion":true},"amenity/car_rental/stadtmobil CarSharing-Station":{"tags":{"name":"stadtmobil CarSharing-Station","amenity":"car_rental"},"name":"stadtmobil CarSharing-Station","icon":"car","geometry":["point","area"],"fields":["operator"],"suggestion":true},"amenity/pharmacy/Rowlands Pharmacy":{"tags":{"name":"Rowlands Pharmacy","amenity":"pharmacy"},"name":"Rowlands Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Boots":{"tags":{"name":"Boots","amenity":"pharmacy"},"name":"Boots","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Marien-Apotheke":{"tags":{"name":"Marien-Apotheke","amenity":"pharmacy"},"name":"Marien-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Mercury Drug":{"tags":{"name":"Mercury Drug","amenity":"pharmacy"},"name":"Mercury Drug","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Löwen-Apotheke":{"tags":{"name":"Löwen-Apotheke","amenity":"pharmacy"},"name":"Löwen-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Superdrug":{"tags":{"name":"Superdrug","amenity":"pharmacy"},"name":"Superdrug","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Sonnen-Apotheke":{"tags":{"name":"Sonnen-Apotheke","amenity":"pharmacy"},"name":"Sonnen-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Rathaus-Apotheke":{"tags":{"name":"Rathaus-Apotheke","amenity":"pharmacy"},"name":"Rathaus-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Engel-Apotheke":{"tags":{"name":"Engel-Apotheke","amenity":"pharmacy"},"name":"Engel-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Hirsch-Apotheke":{"tags":{"name":"Hirsch-Apotheke","amenity":"pharmacy"},"name":"Hirsch-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Stern-Apotheke":{"tags":{"name":"Stern-Apotheke","amenity":"pharmacy"},"name":"Stern-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Lloyds Pharmacy":{"tags":{"name":"Lloyds Pharmacy","amenity":"pharmacy"},"name":"Lloyds Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Rosen-Apotheke":{"tags":{"name":"Rosen-Apotheke","amenity":"pharmacy"},"name":"Rosen-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Stadt-Apotheke":{"tags":{"name":"Stadt-Apotheke","amenity":"pharmacy"},"name":"Stadt-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Markt-Apotheke":{"tags":{"name":"Markt-Apotheke","amenity":"pharmacy"},"name":"Markt-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Аптека":{"tags":{"name":"Аптека","amenity":"pharmacy"},"name":"Аптека","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Pharmasave":{"tags":{"name":"Pharmasave","amenity":"pharmacy"},"name":"Pharmasave","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Brunnen-Apotheke":{"tags":{"name":"Brunnen-Apotheke","amenity":"pharmacy"},"name":"Brunnen-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Shoppers Drug Mart":{"tags":{"name":"Shoppers Drug Mart","amenity":"pharmacy"},"name":"Shoppers Drug Mart","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Apotheke am Markt":{"tags":{"name":"Apotheke am Markt","amenity":"pharmacy"},"name":"Apotheke am Markt","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Alte Apotheke":{"tags":{"name":"Alte Apotheke","amenity":"pharmacy"},"name":"Alte Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Neue Apotheke":{"tags":{"name":"Neue Apotheke","amenity":"pharmacy"},"name":"Neue Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Gintarinė vaistinė":{"tags":{"name":"Gintarinė vaistinė","amenity":"pharmacy"},"name":"Gintarinė vaistinė","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Rats-Apotheke":{"tags":{"name":"Rats-Apotheke","amenity":"pharmacy"},"name":"Rats-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Adler Apotheke":{"tags":{"name":"Adler Apotheke","amenity":"pharmacy"},"name":"Adler Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Pharmacie Centrale":{"tags":{"name":"Pharmacie Centrale","amenity":"pharmacy"},"name":"Pharmacie Centrale","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Walgreens":{"tags":{"name":"Walgreens","amenity":"pharmacy"},"name":"Walgreens","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Rite Aid":{"tags":{"name":"Rite Aid","amenity":"pharmacy"},"name":"Rite Aid","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Apotheke":{"tags":{"name":"Apotheke","amenity":"pharmacy"},"name":"Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Linden-Apotheke":{"tags":{"name":"Linden-Apotheke","amenity":"pharmacy"},"name":"Linden-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Bahnhof-Apotheke":{"tags":{"name":"Bahnhof-Apotheke","amenity":"pharmacy"},"name":"Bahnhof-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Burg-Apotheke":{"tags":{"name":"Burg-Apotheke","amenity":"pharmacy"},"name":"Burg-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Jean Coutu":{"tags":{"name":"Jean Coutu","amenity":"pharmacy"},"name":"Jean Coutu","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Pharmaprix":{"tags":{"name":"Pharmaprix","amenity":"pharmacy"},"name":"Pharmaprix","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmacias Ahumada":{"tags":{"name":"Farmacias Ahumada","amenity":"pharmacy"},"name":"Farmacias Ahumada","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmacia Comunale":{"tags":{"name":"Farmacia Comunale","amenity":"pharmacy"},"name":"Farmacia Comunale","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmacias Cruz Verde":{"tags":{"name":"Farmacias Cruz Verde","amenity":"pharmacy"},"name":"Farmacias Cruz Verde","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Cruz Verde":{"tags":{"name":"Cruz Verde","amenity":"pharmacy"},"name":"Cruz Verde","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Hubertus Apotheke":{"tags":{"name":"Hubertus Apotheke","amenity":"pharmacy"},"name":"Hubertus Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/CVS":{"tags":{"name":"CVS","amenity":"pharmacy"},"name":"CVS","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmacias SalcoBrand":{"tags":{"name":"Farmacias SalcoBrand","amenity":"pharmacy"},"name":"Farmacias SalcoBrand","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Фармация":{"tags":{"name":"Фармация","amenity":"pharmacy"},"name":"Фармация","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Bären-Apotheke":{"tags":{"name":"Bären-Apotheke","amenity":"pharmacy"},"name":"Bären-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Clicks":{"tags":{"name":"Clicks","amenity":"pharmacy"},"name":"Clicks","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/セイジョー":{"tags":{"name":"セイジョー","amenity":"pharmacy"},"name":"セイジョー","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/マツモトキヨシ":{"tags":{"name":"マツモトキヨシ","amenity":"pharmacy"},"name":"マツモトキヨシ","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Dr. Max":{"tags":{"name":"Dr. Max","amenity":"pharmacy"},"name":"Dr. Max","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Вита":{"tags":{"name":"Вита","amenity":"pharmacy"},"name":"Вита","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/サンドラッグ":{"tags":{"name":"サンドラッグ","amenity":"pharmacy"},"name":"サンドラッグ","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Apteka":{"tags":{"name":"Apteka","amenity":"pharmacy"},"name":"Apteka","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Первая помощь":{"tags":{"name":"Первая помощь","amenity":"pharmacy"},"name":"Первая помощь","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Ригла":{"tags":{"name":"Ригла","amenity":"pharmacy"},"name":"Ригла","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Имплозия":{"tags":{"name":"Имплозия","amenity":"pharmacy"},"name":"Имплозия","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Kinney Drugs":{"tags":{"name":"Kinney Drugs","amenity":"pharmacy"},"name":"Kinney Drugs","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Классика":{"tags":{"name":"Классика","amenity":"pharmacy"},"name":"Классика","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Ljekarna":{"tags":{"name":"Ljekarna","amenity":"pharmacy"},"name":"Ljekarna","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/SalcoBrand":{"tags":{"name":"SalcoBrand","amenity":"pharmacy"},"name":"SalcoBrand","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Аптека 36,6":{"tags":{"name":"Аптека 36,6","amenity":"pharmacy"},"name":"Аптека 36,6","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Фармакор":{"tags":{"name":"Фармакор","amenity":"pharmacy"},"name":"Фармакор","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/スギ薬局":{"tags":{"name":"スギ薬局","amenity":"pharmacy"},"name":"スギ薬局","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Аптечный пункт":{"tags":{"name":"Аптечный пункт","amenity":"pharmacy"},"name":"Аптечный пункт","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Невис":{"tags":{"name":"Невис","amenity":"pharmacy"},"name":"Невис","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/トモズ (Tomod's)":{"tags":{"name":"トモズ (Tomod's)","amenity":"pharmacy"},"name":"トモズ (Tomod's)","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Eurovaistinė":{"tags":{"name":"Eurovaistinė","amenity":"pharmacy"},"name":"Eurovaistinė","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmacity":{"tags":{"name":"Farmacity","amenity":"pharmacy"},"name":"Farmacity","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/аптека":{"tags":{"name":"аптека","amenity":"pharmacy"},"name":"аптека","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/The Generics Pharmacy":{"tags":{"name":"The Generics Pharmacy","amenity":"pharmacy"},"name":"The Generics Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmatodo":{"tags":{"name":"Farmatodo","amenity":"pharmacy"},"name":"Farmatodo","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Duane Reade":{"tags":{"name":"Duane Reade","amenity":"pharmacy"},"name":"Duane Reade","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Фармленд":{"tags":{"name":"Фармленд","amenity":"pharmacy"},"name":"Фармленд","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/ドラッグてらしま (Drug Terashima)":{"tags":{"name":"ドラッグてらしま (Drug Terashima)","amenity":"pharmacy"},"name":"ドラッグてらしま (Drug Terashima)","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Арніка":{"tags":{"name":"Арніка","amenity":"pharmacy"},"name":"Арніка","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/ავერსი (Aversi)":{"tags":{"name":"ავერსი (Aversi)","amenity":"pharmacy"},"name":"ავერსი (Aversi)","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmahorro":{"tags":{"name":"Farmahorro","amenity":"pharmacy"},"name":"Farmahorro","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/cafe/Starbucks":{"tags":{"name":"Starbucks","cuisine":"coffee_shop","amenity":"cafe"},"name":"Starbucks","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Cafeteria":{"tags":{"name":"Cafeteria","amenity":"cafe"},"name":"Cafeteria","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Costa":{"tags":{"name":"Costa","amenity":"cafe"},"name":"Costa","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Caffè Nero":{"tags":{"name":"Caffè Nero","amenity":"cafe"},"name":"Caffè Nero","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Кафе":{"tags":{"name":"Кафе","amenity":"cafe"},"name":"Кафе","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Café Central":{"tags":{"name":"Café Central","amenity":"cafe"},"name":"Café Central","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Second Cup":{"tags":{"name":"Second Cup","amenity":"cafe"},"name":"Second Cup","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Dunkin Donuts":{"tags":{"name":"Dunkin Donuts","cuisine":"donut","amenity":"cafe"},"name":"Dunkin Donuts","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Espresso House":{"tags":{"name":"Espresso House","amenity":"cafe"},"name":"Espresso House","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Segafredo":{"tags":{"name":"Segafredo","amenity":"cafe"},"name":"Segafredo","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Coffee Time":{"tags":{"name":"Coffee Time","amenity":"cafe"},"name":"Coffee Time","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Cafe Coffee Day":{"tags":{"name":"Cafe Coffee Day","amenity":"cafe"},"name":"Cafe Coffee Day","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Eiscafe Venezia":{"tags":{"name":"Eiscafe Venezia","amenity":"cafe"},"name":"Eiscafe Venezia","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/スターバックス":{"tags":{"name":"スターバックス","name:en":"Starbucks","amenity":"cafe"},"name":"スターバックス","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Шоколадница":{"tags":{"name":"Шоколадница","amenity":"cafe"},"name":"Шоколадница","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Pret A Manger":{"tags":{"name":"Pret A Manger","amenity":"cafe"},"name":"Pret A Manger","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Столовая":{"tags":{"name":"Столовая","amenity":"cafe"},"name":"Столовая","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/ドトール":{"tags":{"name":"ドトール","name:en":"DOUTOR","amenity":"cafe"},"name":"ドトール","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Tchibo":{"tags":{"name":"Tchibo","amenity":"cafe"},"name":"Tchibo","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Кофе Хауз":{"tags":{"name":"Кофе Хауз","amenity":"cafe"},"name":"Кофе Хауз","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Caribou Coffee":{"tags":{"name":"Caribou Coffee","amenity":"cafe"},"name":"Caribou Coffee","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Уют":{"tags":{"name":"Уют","amenity":"cafe"},"name":"Уют","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Шашлычная":{"tags":{"name":"Шашлычная","amenity":"cafe"},"name":"Шашлычная","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/คาเฟ่ อเมซอน":{"tags":{"name":"คาเฟ่ อเมซอน","amenity":"cafe"},"name":"คาเฟ่ อเมซอน","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Traveler's Coffee":{"tags":{"name":"Traveler's Coffee","amenity":"cafe"},"name":"Traveler's Coffee","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/カフェ・ド・クリエ":{"tags":{"name":"カフェ・ド・クリエ","name:en":"Cafe de CRIE","amenity":"cafe"},"name":"カフェ・ド・クリエ","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"amenity/cafe/Cafe Amazon":{"tags":{"name":"Cafe Amazon","amenity":"cafe"},"name":"Cafe Amazon","icon":"cafe","geometry":["point","area"],"fields":["cuisine","internet_access","address","building_area","opening_hours","smoking"],"suggestion":true},"shop/supermarket/Budgens":{"tags":{"name":"Budgens","shop":"supermarket"},"name":"Budgens","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Morrisons":{"tags":{"name":"Morrisons","shop":"supermarket"},"name":"Morrisons","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Interspar":{"tags":{"name":"Interspar","shop":"supermarket"},"name":"Interspar","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Merkur":{"tags":{"name":"Merkur","shop":"supermarket"},"name":"Merkur","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Sainsbury's":{"tags":{"name":"Sainsbury's","shop":"supermarket"},"name":"Sainsbury's","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Lidl":{"tags":{"name":"Lidl","shop":"supermarket"},"name":"Lidl","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Edeka":{"tags":{"name":"Edeka","shop":"supermarket"},"name":"Edeka","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Coles":{"tags":{"name":"Coles","shop":"supermarket"},"name":"Coles","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Iceland":{"tags":{"name":"Iceland","shop":"supermarket"},"name":"Iceland","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Coop":{"tags":{"name":"Coop","shop":"supermarket"},"name":"Coop","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Tesco":{"tags":{"name":"Tesco","shop":"supermarket"},"name":"Tesco","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Woolworths":{"tags":{"name":"Woolworths","shop":"supermarket"},"name":"Woolworths","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Zielpunkt":{"tags":{"name":"Zielpunkt","shop":"supermarket"},"name":"Zielpunkt","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Nahkauf":{"tags":{"name":"Nahkauf","shop":"supermarket"},"name":"Nahkauf","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Billa":{"tags":{"name":"Billa","shop":"supermarket"},"name":"Billa","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Kaufland":{"tags":{"name":"Kaufland","shop":"supermarket"},"name":"Kaufland","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Plus":{"tags":{"name":"Plus","shop":"supermarket"},"name":"Plus","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ALDI":{"tags":{"name":"ALDI","shop":"supermarket"},"name":"ALDI","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Checkers":{"tags":{"name":"Checkers","shop":"supermarket"},"name":"Checkers","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Tesco Metro":{"tags":{"name":"Tesco Metro","shop":"supermarket"},"name":"Tesco Metro","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/NP":{"tags":{"name":"NP","shop":"supermarket"},"name":"NP","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Penny":{"tags":{"name":"Penny","shop":"supermarket"},"name":"Penny","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Norma":{"tags":{"name":"Norma","shop":"supermarket"},"name":"Norma","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Asda":{"tags":{"name":"Asda","shop":"supermarket"},"name":"Asda","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Netto":{"tags":{"name":"Netto","shop":"supermarket"},"name":"Netto","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Rewe":{"tags":{"name":"Rewe","shop":"supermarket"},"name":"Rewe","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Aldi Süd":{"tags":{"name":"Aldi Süd","shop":"supermarket"},"name":"Aldi Süd","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Real":{"tags":{"name":"Real","shop":"supermarket"},"name":"Real","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/King Soopers":{"tags":{"name":"King Soopers","shop":"supermarket"},"name":"King Soopers","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Kiwi":{"tags":{"name":"Kiwi","shop":"supermarket"},"name":"Kiwi","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Pick n Pay":{"tags":{"name":"Pick n Pay","shop":"supermarket"},"name":"Pick n Pay","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ICA":{"tags":{"name":"ICA","shop":"supermarket"},"name":"ICA","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Tengelmann":{"tags":{"name":"Tengelmann","shop":"supermarket"},"name":"Tengelmann","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Carrefour":{"tags":{"name":"Carrefour","shop":"supermarket"},"name":"Carrefour","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Waitrose":{"tags":{"name":"Waitrose","shop":"supermarket"},"name":"Waitrose","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Spar":{"tags":{"name":"Spar","shop":"supermarket"},"name":"Spar","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Hofer":{"tags":{"name":"Hofer","shop":"supermarket"},"name":"Hofer","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/M-Preis":{"tags":{"name":"M-Preis","shop":"supermarket"},"name":"M-Preis","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/tegut":{"tags":{"name":"tegut","shop":"supermarket"},"name":"tegut","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Sainsbury's Local":{"tags":{"name":"Sainsbury's Local","shop":"supermarket"},"name":"Sainsbury's Local","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/E-Center":{"tags":{"name":"E-Center","shop":"supermarket"},"name":"E-Center","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Aldi Nord":{"tags":{"name":"Aldi Nord","shop":"supermarket"},"name":"Aldi Nord","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/nahkauf":{"tags":{"name":"nahkauf","shop":"supermarket"},"name":"nahkauf","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Meijer":{"tags":{"name":"Meijer","shop":"supermarket"},"name":"Meijer","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Safeway":{"tags":{"name":"Safeway","shop":"supermarket"},"name":"Safeway","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Costco":{"tags":{"name":"Costco","shop":"supermarket"},"name":"Costco","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Albert":{"tags":{"name":"Albert","shop":"supermarket"},"name":"Albert","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Jumbo":{"tags":{"name":"Jumbo","shop":"supermarket"},"name":"Jumbo","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Shoprite":{"tags":{"name":"Shoprite","shop":"supermarket"},"name":"Shoprite","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/MPreis":{"tags":{"name":"MPreis","shop":"supermarket"},"name":"MPreis","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Penny Market":{"tags":{"name":"Penny Market","shop":"supermarket"},"name":"Penny Market","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Tesco Extra":{"tags":{"name":"Tesco Extra","shop":"supermarket"},"name":"Tesco Extra","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Albert Heijn":{"tags":{"name":"Albert Heijn","shop":"supermarket"},"name":"Albert Heijn","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/IGA":{"tags":{"name":"IGA","shop":"supermarket"},"name":"IGA","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Super U":{"tags":{"name":"Super U","shop":"supermarket"},"name":"Super U","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Metro":{"tags":{"name":"Metro","shop":"supermarket"},"name":"Metro","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Neukauf":{"tags":{"name":"Neukauf","shop":"supermarket"},"name":"Neukauf","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Migros":{"tags":{"name":"Migros","shop":"supermarket"},"name":"Migros","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Marktkauf":{"tags":{"name":"Marktkauf","shop":"supermarket"},"name":"Marktkauf","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Delikatesy Centrum":{"tags":{"name":"Delikatesy Centrum","shop":"supermarket"},"name":"Delikatesy Centrum","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/C1000":{"tags":{"name":"C1000","shop":"supermarket"},"name":"C1000","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Hoogvliet":{"tags":{"name":"Hoogvliet","shop":"supermarket"},"name":"Hoogvliet","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Food Basics":{"tags":{"name":"Food Basics","shop":"supermarket"},"name":"Food Basics","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Casino":{"tags":{"name":"Casino","shop":"supermarket"},"name":"Casino","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Penny Markt":{"tags":{"name":"Penny Markt","shop":"supermarket"},"name":"Penny Markt","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Giant":{"tags":{"name":"Giant","shop":"supermarket"},"name":"Giant","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Rema 1000":{"tags":{"name":"Rema 1000","shop":"supermarket"},"name":"Rema 1000","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Kaufpark":{"tags":{"name":"Kaufpark","shop":"supermarket"},"name":"Kaufpark","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ALDI SÜD":{"tags":{"name":"ALDI SÜD","shop":"supermarket"},"name":"ALDI SÜD","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Simply Market":{"tags":{"name":"Simply Market","shop":"supermarket"},"name":"Simply Market","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Konzum":{"tags":{"name":"Konzum","shop":"supermarket"},"name":"Konzum","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Carrefour Express":{"tags":{"name":"Carrefour Express","shop":"supermarket"},"name":"Carrefour Express","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Eurospar":{"tags":{"name":"Eurospar","shop":"supermarket"},"name":"Eurospar","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Mercator":{"tags":{"name":"Mercator","shop":"supermarket"},"name":"Mercator","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Famila":{"tags":{"name":"Famila","shop":"supermarket"},"name":"Famila","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Hemköp":{"tags":{"name":"Hemköp","shop":"supermarket"},"name":"Hemköp","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/real,-":{"tags":{"name":"real,-","shop":"supermarket"},"name":"real,-","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Markant":{"tags":{"name":"Markant","shop":"supermarket"},"name":"Markant","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Volg":{"tags":{"name":"Volg","shop":"supermarket"},"name":"Volg","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Leader Price":{"tags":{"name":"Leader Price","shop":"supermarket"},"name":"Leader Price","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Treff 3000":{"tags":{"name":"Treff 3000","shop":"supermarket"},"name":"Treff 3000","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/SuperBrugsen":{"tags":{"name":"SuperBrugsen","shop":"supermarket"},"name":"SuperBrugsen","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Kaiser's":{"tags":{"name":"Kaiser's","shop":"supermarket"},"name":"Kaiser's","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/K+K":{"tags":{"name":"K+K","shop":"supermarket"},"name":"K+K","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Unimarkt":{"tags":{"name":"Unimarkt","shop":"supermarket"},"name":"Unimarkt","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Carrefour City":{"tags":{"name":"Carrefour City","shop":"supermarket"},"name":"Carrefour City","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Sobeys":{"tags":{"name":"Sobeys","shop":"supermarket"},"name":"Sobeys","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/S-Market":{"tags":{"name":"S-Market","shop":"supermarket"},"name":"S-Market","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Combi":{"tags":{"name":"Combi","shop":"supermarket"},"name":"Combi","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Denner":{"tags":{"name":"Denner","shop":"supermarket"},"name":"Denner","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Konsum":{"tags":{"name":"Konsum","shop":"supermarket"},"name":"Konsum","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Franprix":{"tags":{"name":"Franprix","shop":"supermarket"},"name":"Franprix","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Monoprix":{"tags":{"name":"Monoprix","shop":"supermarket"},"name":"Monoprix","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Diska":{"tags":{"name":"Diska","shop":"supermarket"},"name":"Diska","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/PENNY":{"tags":{"name":"PENNY","shop":"supermarket"},"name":"PENNY","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Dia":{"tags":{"name":"Dia","shop":"supermarket"},"name":"Dia","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Giant Eagle":{"tags":{"name":"Giant Eagle","shop":"supermarket"},"name":"Giant Eagle","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/NORMA":{"tags":{"name":"NORMA","shop":"supermarket"},"name":"NORMA","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/AD Delhaize":{"tags":{"name":"AD Delhaize","shop":"supermarket"},"name":"AD Delhaize","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Auchan":{"tags":{"name":"Auchan","shop":"supermarket"},"name":"Auchan","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Mercadona":{"tags":{"name":"Mercadona","shop":"supermarket"},"name":"Mercadona","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Consum":{"tags":{"name":"Consum","shop":"supermarket"},"name":"Consum","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Carrefour Market":{"tags":{"name":"Carrefour Market","shop":"supermarket"},"name":"Carrefour Market","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Whole Foods":{"tags":{"name":"Whole Foods","shop":"supermarket"},"name":"Whole Foods","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Pam":{"tags":{"name":"Pam","shop":"supermarket"},"name":"Pam","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/sky":{"tags":{"name":"sky","shop":"supermarket"},"name":"sky","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Despar":{"tags":{"name":"Despar","shop":"supermarket"},"name":"Despar","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Eroski":{"tags":{"name":"Eroski","shop":"supermarket"},"name":"Eroski","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Maxi":{"tags":{"name":"Maxi","shop":"supermarket"},"name":"Maxi","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Colruyt":{"tags":{"name":"Colruyt","shop":"supermarket"},"name":"Colruyt","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/The Co-operative":{"tags":{"name":"The Co-operative","shop":"supermarket"},"name":"The Co-operative","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Intermarché":{"tags":{"name":"Intermarché","shop":"supermarket"},"name":"Intermarché","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Delhaize":{"tags":{"name":"Delhaize","shop":"supermarket"},"name":"Delhaize","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/CBA":{"tags":{"name":"CBA","shop":"supermarket"},"name":"CBA","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Shopi":{"tags":{"name":"Shopi","shop":"supermarket"},"name":"Shopi","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Walmart":{"tags":{"name":"Walmart","shop":"supermarket"},"name":"Walmart","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Kroger":{"tags":{"name":"Kroger","shop":"supermarket"},"name":"Kroger","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Albertsons":{"tags":{"name":"Albertsons","shop":"supermarket"},"name":"Albertsons","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Trader Joe's":{"tags":{"name":"Trader Joe's","shop":"supermarket"},"name":"Trader Joe's","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Feneberg":{"tags":{"name":"Feneberg","shop":"supermarket"},"name":"Feneberg","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/denn's Biomarkt":{"tags":{"name":"denn's Biomarkt","shop":"supermarket"},"name":"denn's Biomarkt","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Kvickly":{"tags":{"name":"Kvickly","shop":"supermarket"},"name":"Kvickly","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Makro":{"tags":{"name":"Makro","shop":"supermarket"},"name":"Makro","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Dico":{"tags":{"name":"Dico","shop":"supermarket"},"name":"Dico","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Nah & Frisch":{"tags":{"name":"Nah & Frisch","shop":"supermarket"},"name":"Nah & Frisch","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Champion":{"tags":{"name":"Champion","shop":"supermarket"},"name":"Champion","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ICA Supermarket":{"tags":{"name":"ICA Supermarket","shop":"supermarket"},"name":"ICA Supermarket","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Fakta":{"tags":{"name":"Fakta","shop":"supermarket"},"name":"Fakta","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Магнит":{"tags":{"name":"Магнит","shop":"supermarket"},"name":"Магнит","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Caprabo":{"tags":{"name":"Caprabo","shop":"supermarket"},"name":"Caprabo","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Famiglia Cooperativa":{"tags":{"name":"Famiglia Cooperativa","shop":"supermarket"},"name":"Famiglia Cooperativa","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Народная 7Я семьЯ":{"tags":{"name":"Народная 7Я семьЯ","shop":"supermarket"},"name":"Народная 7Я семьЯ","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Esselunga":{"tags":{"name":"Esselunga","shop":"supermarket"},"name":"Esselunga","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Maxima":{"tags":{"name":"Maxima","shop":"supermarket"},"name":"Maxima","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Wasgau":{"tags":{"name":"Wasgau","shop":"supermarket"},"name":"Wasgau","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Pingo Doce":{"tags":{"name":"Pingo Doce","shop":"supermarket"},"name":"Pingo Doce","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Match":{"tags":{"name":"Match","shop":"supermarket"},"name":"Match","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Profi":{"tags":{"name":"Profi","shop":"supermarket"},"name":"Profi","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Lider":{"tags":{"name":"Lider","shop":"supermarket"},"name":"Lider","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Unimarc":{"tags":{"name":"Unimarc","shop":"supermarket"},"name":"Unimarc","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/The Co-operative Food":{"tags":{"name":"The Co-operative Food","shop":"supermarket"},"name":"The Co-operative Food","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Santa Isabel":{"tags":{"name":"Santa Isabel","shop":"supermarket"},"name":"Santa Isabel","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Седьмой континент":{"tags":{"name":"Седьмой континент","shop":"supermarket"},"name":"Седьмой континент","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/HIT":{"tags":{"name":"HIT","shop":"supermarket"},"name":"HIT","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Rimi":{"tags":{"name":"Rimi","shop":"supermarket"},"name":"Rimi","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Conad":{"tags":{"name":"Conad","shop":"supermarket"},"name":"Conad","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Фуршет":{"tags":{"name":"Фуршет","shop":"supermarket"},"name":"Фуршет","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Willys":{"tags":{"name":"Willys","shop":"supermarket"},"name":"Willys","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Farmfoods":{"tags":{"name":"Farmfoods","shop":"supermarket"},"name":"Farmfoods","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/U Express":{"tags":{"name":"U Express","shop":"supermarket"},"name":"U Express","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Фора":{"tags":{"name":"Фора","shop":"supermarket"},"name":"Фора","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Dunnes Stores":{"tags":{"name":"Dunnes Stores","shop":"supermarket"},"name":"Dunnes Stores","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Сільпо":{"tags":{"name":"Сільпо","shop":"supermarket"},"name":"Сільпо","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/マルエツ":{"tags":{"name":"マルエツ","shop":"supermarket"},"name":"マルエツ","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Piggly Wiggly":{"tags":{"name":"Piggly Wiggly","shop":"supermarket"},"name":"Piggly Wiggly","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Crai":{"tags":{"name":"Crai","shop":"supermarket"},"name":"Crai","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/El Árbol":{"tags":{"name":"El Árbol","shop":"supermarket"},"name":"El Árbol","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Centre Commercial E. Leclerc":{"tags":{"name":"Centre Commercial E. Leclerc","shop":"supermarket"},"name":"Centre Commercial E. Leclerc","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Foodland":{"tags":{"name":"Foodland","shop":"supermarket"},"name":"Foodland","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Super Brugsen":{"tags":{"name":"Super Brugsen","shop":"supermarket"},"name":"Super Brugsen","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Дикси":{"tags":{"name":"Дикси","shop":"supermarket"},"name":"Дикси","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Пятёрочка":{"tags":{"name":"Пятёрочка","shop":"supermarket"},"name":"Пятёрочка","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Publix":{"tags":{"name":"Publix","shop":"supermarket"},"name":"Publix","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Føtex":{"tags":{"name":"Føtex","shop":"supermarket"},"name":"Føtex","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/coop":{"tags":{"name":"coop","shop":"supermarket"},"name":"coop","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Coop Konsum":{"tags":{"name":"Coop Konsum","shop":"supermarket"},"name":"Coop Konsum","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Carrefour Contact":{"tags":{"name":"Carrefour Contact","shop":"supermarket"},"name":"Carrefour Contact","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/No Frills":{"tags":{"name":"No Frills","shop":"supermarket"},"name":"No Frills","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Plodine":{"tags":{"name":"Plodine","shop":"supermarket"},"name":"Plodine","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ADEG":{"tags":{"name":"ADEG","shop":"supermarket"},"name":"ADEG","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Minipreço":{"tags":{"name":"Minipreço","shop":"supermarket"},"name":"Minipreço","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Biedronka":{"tags":{"name":"Biedronka","shop":"supermarket"},"name":"Biedronka","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Eurospin":{"tags":{"name":"Eurospin","shop":"supermarket"},"name":"Eurospin","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Семья":{"tags":{"name":"Семья","shop":"supermarket"},"name":"Семья","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Gadis":{"tags":{"name":"Gadis","shop":"supermarket"},"name":"Gadis","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Евроопт":{"tags":{"name":"Евроопт","shop":"supermarket"},"name":"Евроопт","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Квартал":{"tags":{"name":"Квартал","shop":"supermarket"},"name":"Квартал","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/New World":{"tags":{"name":"New World","shop":"supermarket"},"name":"New World","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Countdown":{"tags":{"name":"Countdown","shop":"supermarket"},"name":"Countdown","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Reliance Fresh":{"tags":{"name":"Reliance Fresh","shop":"supermarket"},"name":"Reliance Fresh","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Stokrotka":{"tags":{"name":"Stokrotka","shop":"supermarket"},"name":"Stokrotka","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Coop Jednota":{"tags":{"name":"Coop Jednota","shop":"supermarket"},"name":"Coop Jednota","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Fred Meyer":{"tags":{"name":"Fred Meyer","shop":"supermarket"},"name":"Fred Meyer","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Irma":{"tags":{"name":"Irma","shop":"supermarket"},"name":"Irma","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Continente":{"tags":{"name":"Continente","shop":"supermarket"},"name":"Continente","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Price Chopper":{"tags":{"name":"Price Chopper","shop":"supermarket"},"name":"Price Chopper","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Game":{"tags":{"name":"Game","shop":"supermarket"},"name":"Game","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Soriana":{"tags":{"name":"Soriana","shop":"supermarket"},"name":"Soriana","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Alimerka":{"tags":{"name":"Alimerka","shop":"supermarket"},"name":"Alimerka","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Piotr i Paweł":{"tags":{"name":"Piotr i Paweł","shop":"supermarket"},"name":"Piotr i Paweł","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Перекресток":{"tags":{"name":"Перекресток","shop":"supermarket"},"name":"Перекресток","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Maxima X":{"tags":{"name":"Maxima X","shop":"supermarket"},"name":"Maxima X","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Карусель":{"tags":{"name":"Карусель","shop":"supermarket"},"name":"Карусель","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ALDI Nord":{"tags":{"name":"ALDI Nord","shop":"supermarket"},"name":"ALDI Nord","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Condis":{"tags":{"name":"Condis","shop":"supermarket"},"name":"Condis","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Sam's Club":{"tags":{"name":"Sam's Club","shop":"supermarket"},"name":"Sam's Club","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Копейка":{"tags":{"name":"Копейка","shop":"supermarket"},"name":"Копейка","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Géant Casino":{"tags":{"name":"Géant Casino","shop":"supermarket"},"name":"Géant Casino","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ASDA":{"tags":{"name":"ASDA","shop":"supermarket"},"name":"ASDA","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Intermarche":{"tags":{"name":"Intermarche","shop":"supermarket"},"name":"Intermarche","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Stop & Shop":{"tags":{"name":"Stop & Shop","shop":"supermarket"},"name":"Stop & Shop","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Food Lion":{"tags":{"name":"Food Lion","shop":"supermarket"},"name":"Food Lion","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Harris Teeter":{"tags":{"name":"Harris Teeter","shop":"supermarket"},"name":"Harris Teeter","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Foodworks":{"tags":{"name":"Foodworks","shop":"supermarket"},"name":"Foodworks","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Polo Market":{"tags":{"name":"Polo Market","shop":"supermarket"},"name":"Polo Market","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Лента":{"tags":{"name":"Лента","shop":"supermarket"},"name":"Лента","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/西友 (SEIYU)":{"tags":{"name":"西友 (SEIYU)","shop":"supermarket"},"name":"西友 (SEIYU)","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/H-E-B":{"tags":{"name":"H-E-B","shop":"supermarket"},"name":"H-E-B","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Атак":{"tags":{"name":"Атак","shop":"supermarket"},"name":"Атак","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Полушка":{"tags":{"name":"Полушка","shop":"supermarket"},"name":"Полушка","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Extra":{"tags":{"name":"Extra","shop":"supermarket"},"name":"Extra","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Sigma":{"tags":{"name":"Sigma","shop":"supermarket"},"name":"Sigma","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/АТБ":{"tags":{"name":"АТБ","shop":"supermarket"},"name":"АТБ","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Bodega Aurrera":{"tags":{"name":"Bodega Aurrera","shop":"supermarket"},"name":"Bodega Aurrera","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Tesco Lotus":{"tags":{"name":"Tesco Lotus","shop":"supermarket"},"name":"Tesco Lotus","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Мария-Ра":{"tags":{"name":"Мария-Ра","shop":"supermarket"},"name":"Мария-Ра","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Магнолия":{"tags":{"name":"Магнолия","shop":"supermarket"},"name":"Магнолия","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Монетка":{"tags":{"name":"Монетка","shop":"supermarket"},"name":"Монетка","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Hy-Vee":{"tags":{"name":"Hy-Vee","shop":"supermarket"},"name":"Hy-Vee","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Walmart Supercenter":{"tags":{"name":"Walmart Supercenter","shop":"supermarket"},"name":"Walmart Supercenter","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Hannaford":{"tags":{"name":"Hannaford","shop":"supermarket"},"name":"Hannaford","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Wegmans":{"tags":{"name":"Wegmans","shop":"supermarket"},"name":"Wegmans","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/業務スーパー":{"tags":{"name":"業務スーパー","shop":"supermarket"},"name":"業務スーパー","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Norfa XL":{"tags":{"name":"Norfa XL","shop":"supermarket"},"name":"Norfa XL","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ヨークマート (YorkMart)":{"tags":{"name":"ヨークマート (YorkMart)","shop":"supermarket"},"name":"ヨークマート (YorkMart)","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Leclerc Drive":{"tags":{"name":"Leclerc Drive","shop":"supermarket"},"name":"Leclerc Drive","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Media Markt":{"tags":{"name":"Media Markt","shop":"electronics"},"name":"Media Markt","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Maplin":{"tags":{"name":"Maplin","shop":"electronics"},"name":"Maplin","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Best Buy":{"tags":{"name":"Best Buy","shop":"electronics"},"name":"Best Buy","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Future Shop":{"tags":{"name":"Future Shop","shop":"electronics"},"name":"Future Shop","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Saturn":{"tags":{"name":"Saturn","shop":"electronics"},"name":"Saturn","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Currys":{"tags":{"name":"Currys","shop":"electronics"},"name":"Currys","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Radio Shack":{"tags":{"name":"Radio Shack","shop":"electronics"},"name":"Radio Shack","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Euronics":{"tags":{"name":"Euronics","shop":"electronics"},"name":"Euronics","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Expert":{"tags":{"name":"Expert","shop":"electronics"},"name":"Expert","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Эльдорадо":{"tags":{"name":"Эльдорадо","shop":"electronics"},"name":"Эльдорадо","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Darty":{"tags":{"name":"Darty","shop":"electronics"},"name":"Darty","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/М.Видео":{"tags":{"name":"М.Видео","shop":"electronics"},"name":"М.Видео","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/ヤマダ電機":{"tags":{"name":"ヤマダ電機","shop":"electronics"},"name":"ヤマダ電機","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/McColl's":{"tags":{"name":"McColl's","shop":"convenience"},"name":"McColl's","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Tesco Express":{"tags":{"name":"Tesco Express","shop":"convenience"},"name":"Tesco Express","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/One Stop":{"tags":{"name":"One Stop","shop":"convenience"},"name":"One Stop","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Londis":{"tags":{"name":"Londis","shop":"convenience"},"name":"Londis","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/7-Eleven":{"tags":{"name":"7-Eleven","shop":"convenience"},"name":"7-Eleven","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Sale":{"tags":{"name":"Sale","shop":"convenience"},"name":"Sale","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Siwa":{"tags":{"name":"Siwa","shop":"convenience"},"name":"Siwa","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/COOP Jednota":{"tags":{"name":"COOP Jednota","shop":"convenience"},"name":"COOP Jednota","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Mac's":{"tags":{"name":"Mac's","shop":"convenience"},"name":"Mac's","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Alepa":{"tags":{"name":"Alepa","shop":"convenience"},"name":"Alepa","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Hasty Market":{"tags":{"name":"Hasty Market","shop":"convenience"},"name":"Hasty Market","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/K-Market":{"tags":{"name":"K-Market","shop":"convenience"},"name":"K-Market","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Costcutter":{"tags":{"name":"Costcutter","shop":"convenience"},"name":"Costcutter","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Valintatalo":{"tags":{"name":"Valintatalo","shop":"convenience"},"name":"Valintatalo","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Circle K":{"tags":{"name":"Circle K","shop":"convenience"},"name":"Circle K","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/セブンイレブン":{"tags":{"name":"セブンイレブン","name:en":"7-Eleven","shop":"convenience"},"name":"セブンイレブン","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ローソン":{"tags":{"name":"ローソン","name:en":"LAWSON","shop":"convenience"},"name":"ローソン","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Petit Casino":{"tags":{"name":"Petit Casino","shop":"convenience"},"name":"Petit Casino","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Mace":{"tags":{"name":"Mace","shop":"convenience"},"name":"Mace","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Mini Market":{"tags":{"name":"Mini Market","shop":"convenience"},"name":"Mini Market","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Nisa Local":{"tags":{"name":"Nisa Local","shop":"convenience"},"name":"Nisa Local","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Dorfladen":{"tags":{"name":"Dorfladen","shop":"convenience"},"name":"Dorfladen","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Продукты":{"tags":{"name":"Продукты","shop":"convenience"},"name":"Продукты","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Mini Stop":{"tags":{"name":"Mini Stop","shop":"convenience"},"name":"Mini Stop","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/LAWSON":{"tags":{"name":"LAWSON","shop":"convenience"},"name":"LAWSON","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/デイリーヤマザキ":{"tags":{"name":"デイリーヤマザキ","shop":"convenience"},"name":"デイリーヤマザキ","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Надежда":{"tags":{"name":"Надежда","shop":"convenience"},"name":"Надежда","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Nisa":{"tags":{"name":"Nisa","shop":"convenience"},"name":"Nisa","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Premier":{"tags":{"name":"Premier","shop":"convenience"},"name":"Premier","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ABC":{"tags":{"name":"ABC","shop":"convenience"},"name":"ABC","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ミニストップ":{"tags":{"name":"ミニストップ","name:en":"MINISTOP","shop":"convenience"},"name":"ミニストップ","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/サンクス":{"tags":{"name":"サンクス","name:en":"sunkus","shop":"convenience"},"name":"サンクス","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/スリーエフ":{"tags":{"name":"スリーエフ","shop":"convenience"},"name":"スリーエフ","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/8 à Huit":{"tags":{"name":"8 à Huit","shop":"convenience"},"name":"8 à Huit","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Żabka":{"tags":{"name":"Żabka","shop":"convenience"},"name":"Żabka","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Almacen":{"tags":{"name":"Almacen","shop":"convenience"},"name":"Almacen","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Vival":{"tags":{"name":"Vival","shop":"convenience"},"name":"Vival","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/FamilyMart":{"tags":{"name":"FamilyMart","shop":"convenience"},"name":"FamilyMart","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ファミリーマート":{"tags":{"name":"ファミリーマート","name:en":"FamilyMart","shop":"convenience"},"name":"ファミリーマート","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Sunkus":{"tags":{"name":"Sunkus","shop":"convenience"},"name":"Sunkus","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/セブンイレブン(Seven-Eleven)":{"tags":{"name":"セブンイレブン(Seven-Eleven)","shop":"convenience"},"name":"セブンイレブン(Seven-Eleven)","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Jednota":{"tags":{"name":"Jednota","shop":"convenience"},"name":"Jednota","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Магазин":{"tags":{"name":"Магазин","shop":"convenience"},"name":"Магазин","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Гастроном":{"tags":{"name":"Гастроном","shop":"convenience"},"name":"Гастроном","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Centra":{"tags":{"name":"Centra","shop":"convenience"},"name":"Centra","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/サークルK":{"tags":{"name":"サークルK","name:en":"Circle K","shop":"convenience"},"name":"サークルK","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Wawa":{"tags":{"name":"Wawa","shop":"convenience"},"name":"Wawa","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Proxi":{"tags":{"name":"Proxi","shop":"convenience"},"name":"Proxi","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Универсам":{"tags":{"name":"Универсам","shop":"convenience"},"name":"Универсам","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Groszek":{"tags":{"name":"Groszek","shop":"convenience"},"name":"Groszek","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Select":{"tags":{"name":"Select","shop":"convenience"},"name":"Select","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Večerka":{"tags":{"name":"Večerka","shop":"convenience"},"name":"Večerka","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Potraviny":{"tags":{"name":"Potraviny","shop":"convenience"},"name":"Potraviny","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Смак":{"tags":{"name":"Смак","shop":"convenience"},"name":"Смак","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Эконом":{"tags":{"name":"Эконом","shop":"convenience"},"name":"Эконом","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Березка":{"tags":{"name":"Березка","shop":"convenience"},"name":"Березка","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Społem":{"tags":{"name":"Społem","shop":"convenience"},"name":"Społem","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Cumberland Farms":{"tags":{"name":"Cumberland Farms","shop":"convenience"},"name":"Cumberland Farms","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Tesco Lotus Express":{"tags":{"name":"Tesco Lotus Express","shop":"convenience"},"name":"Tesco Lotus Express","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Kiosk":{"tags":{"name":"Kiosk","shop":"convenience"},"name":"Kiosk","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Sklep spożywczy":{"tags":{"name":"Sklep spożywczy","shop":"convenience"},"name":"Sklep spożywczy","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/24 часа":{"tags":{"name":"24 часа","shop":"convenience"},"name":"24 часа","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Минимаркет":{"tags":{"name":"Минимаркет","shop":"convenience"},"name":"Минимаркет","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Oxxo":{"tags":{"name":"Oxxo","shop":"convenience"},"name":"Oxxo","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/abc":{"tags":{"name":"abc","shop":"convenience"},"name":"abc","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/7/11":{"tags":{"name":"7/11","shop":"convenience"},"name":"7/11","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Stewart's":{"tags":{"name":"Stewart's","shop":"convenience"},"name":"Stewart's","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Продукти":{"tags":{"name":"Продукти","shop":"convenience"},"name":"Продукти","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ローソンストア100 (LAWSON STORE 100)":{"tags":{"name":"ローソンストア100 (LAWSON STORE 100)","shop":"convenience"},"name":"ローソンストア100 (LAWSON STORE 100)","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Радуга":{"tags":{"name":"Радуга","shop":"convenience"},"name":"Радуга","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ローソンストア100":{"tags":{"name":"ローソンストア100","shop":"convenience"},"name":"ローソンストア100","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/เซเว่นอีเลฟเว่น":{"tags":{"name":"เซเว่นอีเลฟเว่น","shop":"convenience"},"name":"เซเว่นอีเลฟเว่น","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Фортуна":{"tags":{"name":"Фортуна","shop":"convenience"},"name":"Фортуна","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Picard":{"tags":{"name":"Picard","shop":"convenience"},"name":"Picard","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Four Square":{"tags":{"name":"Four Square","shop":"convenience"},"name":"Four Square","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Визит":{"tags":{"name":"Визит","shop":"convenience"},"name":"Визит","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Авоська":{"tags":{"name":"Авоська","shop":"convenience"},"name":"Авоська","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Dollar General":{"tags":{"name":"Dollar General","shop":"convenience"},"name":"Dollar General","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Studenac":{"tags":{"name":"Studenac","shop":"convenience"},"name":"Studenac","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Central Convenience Store":{"tags":{"name":"Central Convenience Store","shop":"convenience"},"name":"Central Convenience Store","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/продукты":{"tags":{"name":"продукты","shop":"convenience"},"name":"продукты","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Кулинария":{"tags":{"name":"Кулинария","shop":"convenience"},"name":"Кулинария","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/全家":{"tags":{"name":"全家","shop":"convenience"},"name":"全家","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Мечта":{"tags":{"name":"Мечта","shop":"convenience"},"name":"Мечта","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Epicerie":{"tags":{"name":"Epicerie","shop":"convenience"},"name":"Epicerie","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Кировский":{"tags":{"name":"Кировский","shop":"convenience"},"name":"Кировский","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Food Mart":{"tags":{"name":"Food Mart","shop":"convenience"},"name":"Food Mart","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Delikatesy":{"tags":{"name":"Delikatesy","shop":"convenience"},"name":"Delikatesy","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ポプラ":{"tags":{"name":"ポプラ","shop":"convenience"},"name":"ポプラ","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Lewiatan":{"tags":{"name":"Lewiatan","shop":"convenience"},"name":"Lewiatan","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Продуктовый магазин":{"tags":{"name":"Продуктовый магазин","shop":"convenience"},"name":"Продуктовый магазин","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Продуктовый":{"tags":{"name":"Продуктовый","shop":"convenience"},"name":"Продуктовый","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/セイコーマート (Seicomart)":{"tags":{"name":"セイコーマート (Seicomart)","shop":"convenience"},"name":"セイコーマート (Seicomart)","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Виктория":{"tags":{"name":"Виктория","shop":"convenience"},"name":"Виктория","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Весна":{"tags":{"name":"Весна","shop":"convenience"},"name":"Весна","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Mini Market Non-Stop":{"tags":{"name":"Mini Market Non-Stop","shop":"convenience"},"name":"Mini Market Non-Stop","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Копеечка":{"tags":{"name":"Копеечка","shop":"convenience"},"name":"Копеечка","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Royal Farms":{"tags":{"name":"Royal Farms","shop":"convenience"},"name":"Royal Farms","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Alfamart":{"tags":{"name":"Alfamart","shop":"convenience"},"name":"Alfamart","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Indomaret":{"tags":{"name":"Indomaret","shop":"convenience"},"name":"Indomaret","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/магазин":{"tags":{"name":"магазин","shop":"convenience"},"name":"магазин","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/全家便利商店":{"tags":{"name":"全家便利商店","shop":"convenience"},"name":"全家便利商店","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Boutique":{"tags":{"name":"Boutique","shop":"convenience"},"name":"Boutique","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/მარკეტი (Market)":{"tags":{"name":"მარკეტი (Market)","shop":"convenience"},"name":"მარკეტი (Market)","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Stores":{"tags":{"name":"Stores","shop":"convenience"},"name":"Stores","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/dm":{"tags":{"name":"dm","shop":"chemist"},"name":"dm","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Müller":{"tags":{"name":"Müller","shop":"chemist"},"name":"Müller","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Schlecker":{"tags":{"name":"Schlecker","shop":"chemist"},"name":"Schlecker","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Etos":{"tags":{"name":"Etos","shop":"chemist"},"name":"Etos","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Bipa":{"tags":{"name":"Bipa","shop":"chemist"},"name":"Bipa","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Rossmann":{"tags":{"name":"Rossmann","shop":"chemist"},"name":"Rossmann","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/DM Drogeriemarkt":{"tags":{"name":"DM Drogeriemarkt","shop":"chemist"},"name":"DM Drogeriemarkt","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Ihr Platz":{"tags":{"name":"Ihr Platz","shop":"chemist"},"name":"Ihr Platz","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Douglas":{"tags":{"name":"Douglas","shop":"chemist"},"name":"Douglas","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Kruidvat":{"tags":{"name":"Kruidvat","shop":"chemist"},"name":"Kruidvat","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Kwik Fit":{"tags":{"name":"Kwik Fit","shop":"car_repair"},"name":"Kwik Fit","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/ATU":{"tags":{"name":"ATU","shop":"car_repair"},"name":"ATU","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Midas":{"tags":{"name":"Midas","shop":"car_repair"},"name":"Midas","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Feu Vert":{"tags":{"name":"Feu Vert","shop":"car_repair"},"name":"Feu Vert","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Norauto":{"tags":{"name":"Norauto","shop":"car_repair"},"name":"Norauto","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Speedy":{"tags":{"name":"Speedy","shop":"car_repair"},"name":"Speedy","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Pit Stop":{"tags":{"name":"Pit Stop","shop":"car_repair"},"name":"Pit Stop","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Jiffy Lube":{"tags":{"name":"Jiffy Lube","shop":"car_repair"},"name":"Jiffy Lube","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Шиномонтаж":{"tags":{"name":"Шиномонтаж","shop":"car_repair"},"name":"Шиномонтаж","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/СТО":{"tags":{"name":"СТО","shop":"car_repair"},"name":"СТО","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/O'Reilly Auto Parts":{"tags":{"name":"O'Reilly Auto Parts","shop":"car_repair"},"name":"O'Reilly Auto Parts","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Carglass":{"tags":{"name":"Carglass","shop":"car_repair"},"name":"Carglass","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/шиномонтаж":{"tags":{"name":"шиномонтаж","shop":"car_repair"},"name":"шиномонтаж","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Euromaster":{"tags":{"name":"Euromaster","shop":"car_repair"},"name":"Euromaster","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Firestone":{"tags":{"name":"Firestone","shop":"car_repair"},"name":"Firestone","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Автосервис":{"tags":{"name":"Автосервис","shop":"car_repair"},"name":"Автосервис","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Advance Auto Parts":{"tags":{"name":"Advance Auto Parts","shop":"car_repair"},"name":"Advance Auto Parts","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Roady":{"tags":{"name":"Roady","shop":"car_repair"},"name":"Roady","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/IKEA":{"tags":{"name":"IKEA","shop":"furniture"},"name":"IKEA","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Jysk":{"tags":{"name":"Jysk","shop":"furniture"},"name":"Jysk","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Roller":{"tags":{"name":"Roller","shop":"furniture"},"name":"Roller","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Dänisches Bettenlager":{"tags":{"name":"Dänisches Bettenlager","shop":"furniture"},"name":"Dänisches Bettenlager","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Conforama":{"tags":{"name":"Conforama","shop":"furniture"},"name":"Conforama","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Matratzen Concord":{"tags":{"name":"Matratzen Concord","shop":"furniture"},"name":"Matratzen Concord","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Мебель":{"tags":{"name":"Мебель","shop":"furniture"},"name":"Мебель","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/But":{"tags":{"name":"But","shop":"furniture"},"name":"But","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Hornbach":{"tags":{"name":"Hornbach","shop":"doityourself"},"name":"Hornbach","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/B&Q":{"tags":{"name":"B&Q","shop":"doityourself"},"name":"B&Q","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Hubo":{"tags":{"name":"Hubo","shop":"doityourself"},"name":"Hubo","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Mr Bricolage":{"tags":{"name":"Mr Bricolage","shop":"doityourself"},"name":"Mr Bricolage","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Gamma":{"tags":{"name":"Gamma","shop":"doityourself"},"name":"Gamma","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/OBI":{"tags":{"name":"OBI","shop":"doityourself"},"name":"OBI","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Lowes":{"tags":{"name":"Lowes","shop":"doityourself"},"name":"Lowes","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Wickes":{"tags":{"name":"Wickes","shop":"doityourself"},"name":"Wickes","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Hagebau":{"tags":{"name":"Hagebau","shop":"doityourself"},"name":"Hagebau","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Max Bahr":{"tags":{"name":"Max Bahr","shop":"doityourself"},"name":"Max Bahr","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Castorama":{"tags":{"name":"Castorama","shop":"doityourself"},"name":"Castorama","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Rona":{"tags":{"name":"Rona","shop":"doityourself"},"name":"Rona","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Home Depot":{"tags":{"name":"Home Depot","shop":"doityourself"},"name":"Home Depot","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Toom Baumarkt":{"tags":{"name":"Toom Baumarkt","shop":"doityourself"},"name":"Toom Baumarkt","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Homebase":{"tags":{"name":"Homebase","shop":"doityourself"},"name":"Homebase","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Baumax":{"tags":{"name":"Baumax","shop":"doityourself"},"name":"Baumax","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Lagerhaus":{"tags":{"name":"Lagerhaus","shop":"doityourself"},"name":"Lagerhaus","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Bauhaus":{"tags":{"name":"Bauhaus","shop":"doityourself"},"name":"Bauhaus","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Canadian Tire":{"tags":{"name":"Canadian Tire","shop":"doityourself"},"name":"Canadian Tire","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Leroy Merlin":{"tags":{"name":"Leroy Merlin","shop":"doityourself"},"name":"Leroy Merlin","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Hellweg":{"tags":{"name":"Hellweg","shop":"doityourself"},"name":"Hellweg","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Brico":{"tags":{"name":"Brico","shop":"doityourself"},"name":"Brico","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Bricomarché":{"tags":{"name":"Bricomarché","shop":"doityourself"},"name":"Bricomarché","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Toom":{"tags":{"name":"Toom","shop":"doityourself"},"name":"Toom","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Hagebaumarkt":{"tags":{"name":"Hagebaumarkt","shop":"doityourself"},"name":"Hagebaumarkt","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Praktiker":{"tags":{"name":"Praktiker","shop":"doityourself"},"name":"Praktiker","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Menards":{"tags":{"name":"Menards","shop":"doityourself"},"name":"Menards","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Weldom":{"tags":{"name":"Weldom","shop":"doityourself"},"name":"Weldom","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Bunnings Warehouse":{"tags":{"name":"Bunnings Warehouse","shop":"doityourself"},"name":"Bunnings Warehouse","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Ace Hardware":{"tags":{"name":"Ace Hardware","shop":"doityourself"},"name":"Ace Hardware","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Home Hardware":{"tags":{"name":"Home Hardware","shop":"doityourself"},"name":"Home Hardware","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Стройматериалы":{"tags":{"name":"Стройматериалы","shop":"doityourself"},"name":"Стройматериалы","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Bricorama":{"tags":{"name":"Bricorama","shop":"doityourself"},"name":"Bricorama","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Point P":{"tags":{"name":"Point P","shop":"doityourself"},"name":"Point P","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/stationery/Staples":{"tags":{"name":"Staples","shop":"stationery"},"name":"Staples","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/stationery/McPaper":{"tags":{"name":"McPaper","shop":"stationery"},"name":"McPaper","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/stationery/Office Depot":{"tags":{"name":"Office Depot","shop":"stationery"},"name":"Office Depot","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/stationery/Канцтовары":{"tags":{"name":"Канцтовары","shop":"stationery"},"name":"Канцтовары","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car/Skoda":{"tags":{"name":"Skoda","shop":"car"},"name":"Skoda","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/BMW":{"tags":{"name":"BMW","shop":"car"},"name":"BMW","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Citroen":{"tags":{"name":"Citroen","shop":"car"},"name":"Citroen","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Renault":{"tags":{"name":"Renault","shop":"car"},"name":"Renault","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Mercedes-Benz":{"tags":{"name":"Mercedes-Benz","shop":"car"},"name":"Mercedes-Benz","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Volvo":{"tags":{"name":"Volvo","shop":"car"},"name":"Volvo","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Ford":{"tags":{"name":"Ford","shop":"car"},"name":"Ford","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Volkswagen":{"tags":{"name":"Volkswagen","shop":"car"},"name":"Volkswagen","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Mazda":{"tags":{"name":"Mazda","shop":"car"},"name":"Mazda","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Mitsubishi":{"tags":{"name":"Mitsubishi","shop":"car"},"name":"Mitsubishi","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Fiat":{"tags":{"name":"Fiat","shop":"car"},"name":"Fiat","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Автозапчасти":{"tags":{"name":"Автозапчасти","shop":"car"},"name":"Автозапчасти","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Opel":{"tags":{"name":"Opel","shop":"car"},"name":"Opel","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Audi":{"tags":{"name":"Audi","shop":"car"},"name":"Audi","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Toyota":{"tags":{"name":"Toyota","shop":"car"},"name":"Toyota","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Nissan":{"tags":{"name":"Nissan","shop":"car"},"name":"Nissan","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Suzuki":{"tags":{"name":"Suzuki","shop":"car"},"name":"Suzuki","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Honda":{"tags":{"name":"Honda","shop":"car"},"name":"Honda","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Peugeot":{"tags":{"name":"Peugeot","shop":"car"},"name":"Peugeot","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Hyundai":{"tags":{"name":"Hyundai","shop":"car"},"name":"Hyundai","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Subaru":{"tags":{"name":"Subaru","shop":"car"},"name":"Subaru","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Chevrolet":{"tags":{"name":"Chevrolet","shop":"car"},"name":"Chevrolet","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Автомагазин":{"tags":{"name":"Автомагазин","shop":"car"},"name":"Автомагазин","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/clothes/Matalan":{"tags":{"name":"Matalan","shop":"clothes"},"name":"Matalan","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/KiK":{"tags":{"name":"KiK","shop":"clothes"},"name":"KiK","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/H&M":{"tags":{"name":"H&M","shop":"clothes"},"name":"H&M","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Urban Outfitters":{"tags":{"name":"Urban Outfitters","shop":"clothes"},"name":"Urban Outfitters","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Vögele":{"tags":{"name":"Vögele","shop":"clothes"},"name":"Vögele","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Zeeman":{"tags":{"name":"Zeeman","shop":"clothes"},"name":"Zeeman","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Takko":{"tags":{"name":"Takko","shop":"clothes"},"name":"Takko","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/C&A":{"tags":{"name":"C&A","shop":"clothes"},"name":"C&A","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Zara":{"tags":{"name":"Zara","shop":"clothes"},"name":"Zara","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Vero Moda":{"tags":{"name":"Vero Moda","shop":"clothes"},"name":"Vero Moda","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/NKD":{"tags":{"name":"NKD","shop":"clothes"},"name":"NKD","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Ernsting's family":{"tags":{"name":"Ernsting's family","shop":"clothes"},"name":"Ernsting's family","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Winners":{"tags":{"name":"Winners","shop":"clothes"},"name":"Winners","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/River Island":{"tags":{"name":"River Island","shop":"clothes"},"name":"River Island","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Next":{"tags":{"name":"Next","shop":"clothes"},"name":"Next","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Gap":{"tags":{"name":"Gap","shop":"clothes"},"name":"Gap","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Adidas":{"tags":{"name":"Adidas","shop":"clothes"},"name":"Adidas","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Mr Price":{"tags":{"name":"Mr Price","shop":"clothes"},"name":"Mr Price","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Pep":{"tags":{"name":"Pep","shop":"clothes"},"name":"Pep","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Edgars":{"tags":{"name":"Edgars","shop":"clothes"},"name":"Edgars","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Ackermans":{"tags":{"name":"Ackermans","shop":"clothes"},"name":"Ackermans","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Truworths":{"tags":{"name":"Truworths","shop":"clothes"},"name":"Truworths","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Ross":{"tags":{"name":"Ross","shop":"clothes"},"name":"Ross","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Burton":{"tags":{"name":"Burton","shop":"clothes"},"name":"Burton","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Dorothy Perkins":{"tags":{"name":"Dorothy Perkins","shop":"clothes"},"name":"Dorothy Perkins","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Lindex":{"tags":{"name":"Lindex","shop":"clothes"},"name":"Lindex","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/s.Oliver":{"tags":{"name":"s.Oliver","shop":"clothes"},"name":"s.Oliver","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Cecil":{"tags":{"name":"Cecil","shop":"clothes"},"name":"Cecil","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Dress Barn":{"tags":{"name":"Dress Barn","shop":"clothes"},"name":"Dress Barn","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Old Navy":{"tags":{"name":"Old Navy","shop":"clothes"},"name":"Old Navy","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Jack & Jones":{"tags":{"name":"Jack & Jones","shop":"clothes"},"name":"Jack & Jones","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Pimkie":{"tags":{"name":"Pimkie","shop":"clothes"},"name":"Pimkie","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Esprit":{"tags":{"name":"Esprit","shop":"clothes"},"name":"Esprit","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Primark":{"tags":{"name":"Primark","shop":"clothes"},"name":"Primark","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Bonita":{"tags":{"name":"Bonita","shop":"clothes"},"name":"Bonita","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Mexx":{"tags":{"name":"Mexx","shop":"clothes"},"name":"Mexx","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Gerry Weber":{"tags":{"name":"Gerry Weber","shop":"clothes"},"name":"Gerry Weber","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Tally Weijl":{"tags":{"name":"Tally Weijl","shop":"clothes"},"name":"Tally Weijl","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Mango":{"tags":{"name":"Mango","shop":"clothes"},"name":"Mango","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/TK Maxx":{"tags":{"name":"TK Maxx","shop":"clothes"},"name":"TK Maxx","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Benetton":{"tags":{"name":"Benetton","shop":"clothes"},"name":"Benetton","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Ulla Popken":{"tags":{"name":"Ulla Popken","shop":"clothes"},"name":"Ulla Popken","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/AWG":{"tags":{"name":"AWG","shop":"clothes"},"name":"AWG","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Tommy Hilfiger":{"tags":{"name":"Tommy Hilfiger","shop":"clothes"},"name":"Tommy Hilfiger","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/New Yorker":{"tags":{"name":"New Yorker","shop":"clothes"},"name":"New Yorker","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Orsay":{"tags":{"name":"Orsay","shop":"clothes"},"name":"Orsay","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Jeans Fritz":{"tags":{"name":"Jeans Fritz","shop":"clothes"},"name":"Jeans Fritz","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Charles Vögele":{"tags":{"name":"Charles Vögele","shop":"clothes"},"name":"Charles Vögele","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/New Look":{"tags":{"name":"New Look","shop":"clothes"},"name":"New Look","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Lacoste":{"tags":{"name":"Lacoste","shop":"clothes"},"name":"Lacoste","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Etam":{"tags":{"name":"Etam","shop":"clothes"},"name":"Etam","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Kiabi":{"tags":{"name":"Kiabi","shop":"clothes"},"name":"Kiabi","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Jack Wolfskin":{"tags":{"name":"Jack Wolfskin","shop":"clothes"},"name":"Jack Wolfskin","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/American Apparel":{"tags":{"name":"American Apparel","shop":"clothes"},"name":"American Apparel","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Men's Wearhouse":{"tags":{"name":"Men's Wearhouse","shop":"clothes"},"name":"Men's Wearhouse","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Intimissimi":{"tags":{"name":"Intimissimi","shop":"clothes"},"name":"Intimissimi","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/United Colors of Benetton":{"tags":{"name":"United Colors of Benetton","shop":"clothes"},"name":"United Colors of Benetton","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Jules":{"tags":{"name":"Jules","shop":"clothes"},"name":"Jules","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Second Hand":{"tags":{"name":"Second Hand","shop":"clothes"},"name":"Second Hand","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/AOKI":{"tags":{"name":"AOKI","shop":"clothes"},"name":"AOKI","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Calzedonia":{"tags":{"name":"Calzedonia","shop":"clothes"},"name":"Calzedonia","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/洋服の青山":{"tags":{"name":"洋服の青山","shop":"clothes"},"name":"洋服の青山","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Levi's":{"tags":{"name":"Levi's","shop":"clothes"},"name":"Levi's","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Celio":{"tags":{"name":"Celio","shop":"clothes"},"name":"Celio","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/TJ Maxx":{"tags":{"name":"TJ Maxx","shop":"clothes"},"name":"TJ Maxx","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Promod":{"tags":{"name":"Promod","shop":"clothes"},"name":"Promod","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Street One":{"tags":{"name":"Street One","shop":"clothes"},"name":"Street One","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/ユニクロ":{"tags":{"name":"ユニクロ","shop":"clothes"},"name":"ユニクロ","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Banana Republic":{"tags":{"name":"Banana Republic","shop":"clothes"},"name":"Banana Republic","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Одежда":{"tags":{"name":"Одежда","shop":"clothes"},"name":"Одежда","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Marshalls":{"tags":{"name":"Marshalls","shop":"clothes"},"name":"Marshalls","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/La Halle":{"tags":{"name":"La Halle","shop":"clothes"},"name":"La Halle","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Peacocks":{"tags":{"name":"Peacocks","shop":"clothes"},"name":"Peacocks","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/しまむら":{"tags":{"name":"しまむら","shop":"clothes"},"name":"しまむら","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/books/Bruna":{"tags":{"name":"Bruna","shop":"books"},"name":"Bruna","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/books/Waterstones":{"tags":{"name":"Waterstones","shop":"books"},"name":"Waterstones","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/books/Libro":{"tags":{"name":"Libro","shop":"books"},"name":"Libro","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/books/Barnes & Noble":{"tags":{"name":"Barnes & Noble","shop":"books"},"name":"Barnes & Noble","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/books/Weltbild":{"tags":{"name":"Weltbild","shop":"books"},"name":"Weltbild","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/books/Thalia":{"tags":{"name":"Thalia","shop":"books"},"name":"Thalia","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/books/Книги":{"tags":{"name":"Книги","shop":"books"},"name":"Книги","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Debenhams":{"tags":{"name":"Debenhams","shop":"department_store"},"name":"Debenhams","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Karstadt":{"tags":{"name":"Karstadt","shop":"department_store"},"name":"Karstadt","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Kmart":{"tags":{"name":"Kmart","shop":"department_store"},"name":"Kmart","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Target":{"tags":{"name":"Target","shop":"department_store"},"name":"Target","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Galeria Kaufhof":{"tags":{"name":"Galeria Kaufhof","shop":"department_store"},"name":"Galeria Kaufhof","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Marks & Spencer":{"tags":{"name":"Marks & Spencer","shop":"department_store"},"name":"Marks & Spencer","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Big W":{"tags":{"name":"Big W","shop":"department_store"},"name":"Big W","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Woolworth":{"tags":{"name":"Woolworth","shop":"department_store"},"name":"Woolworth","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Универмаг":{"tags":{"name":"Универмаг","shop":"department_store"},"name":"Универмаг","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Sears":{"tags":{"name":"Sears","shop":"department_store"},"name":"Sears","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Kohl's":{"tags":{"name":"Kohl's","shop":"department_store"},"name":"Kohl's","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Macy's":{"tags":{"name":"Macy's","shop":"department_store"},"name":"Macy's","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/JCPenney":{"tags":{"name":"JCPenney","shop":"department_store"},"name":"JCPenney","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/alcohol/Alko":{"tags":{"name":"Alko","shop":"alcohol"},"name":"Alko","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/The Beer Store":{"tags":{"name":"The Beer Store","shop":"alcohol"},"name":"The Beer Store","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Systembolaget":{"tags":{"name":"Systembolaget","shop":"alcohol"},"name":"Systembolaget","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/LCBO":{"tags":{"name":"LCBO","shop":"alcohol"},"name":"LCBO","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Ароматный мир":{"tags":{"name":"Ароматный мир","shop":"alcohol"},"name":"Ароматный мир","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Bargain Booze":{"tags":{"name":"Bargain Booze","shop":"alcohol"},"name":"Bargain Booze","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Nicolas":{"tags":{"name":"Nicolas","shop":"alcohol"},"name":"Nicolas","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/BWS":{"tags":{"name":"BWS","shop":"alcohol"},"name":"BWS","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Botilleria":{"tags":{"name":"Botilleria","shop":"alcohol"},"name":"Botilleria","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/SAQ":{"tags":{"name":"SAQ","shop":"alcohol"},"name":"SAQ","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Gall & Gall":{"tags":{"name":"Gall & Gall","shop":"alcohol"},"name":"Gall & Gall","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Живое пиво":{"tags":{"name":"Живое пиво","shop":"alcohol"},"name":"Живое пиво","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/bakery/Kamps":{"tags":{"name":"Kamps","shop":"bakery"},"name":"Kamps","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Banette":{"tags":{"name":"Banette","shop":"bakery"},"name":"Banette","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Bäckerei Schmidt":{"tags":{"name":"Bäckerei Schmidt","shop":"bakery"},"name":"Bäckerei Schmidt","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Anker":{"tags":{"name":"Anker","shop":"bakery"},"name":"Anker","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Hofpfisterei":{"tags":{"name":"Hofpfisterei","shop":"bakery"},"name":"Hofpfisterei","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Greggs":{"tags":{"name":"Greggs","shop":"bakery"},"name":"Greggs","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Oebel":{"tags":{"name":"Oebel","shop":"bakery"},"name":"Oebel","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Boulangerie":{"tags":{"name":"Boulangerie","shop":"bakery"},"name":"Boulangerie","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Stadtbäckerei":{"tags":{"name":"Stadtbäckerei","shop":"bakery"},"name":"Stadtbäckerei","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Steinecke":{"tags":{"name":"Steinecke","shop":"bakery"},"name":"Steinecke","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Ihle":{"tags":{"name":"Ihle","shop":"bakery"},"name":"Ihle","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Goldilocks":{"tags":{"name":"Goldilocks","shop":"bakery"},"name":"Goldilocks","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Dat Backhus":{"tags":{"name":"Dat Backhus","shop":"bakery"},"name":"Dat Backhus","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/K&U":{"tags":{"name":"K&U","shop":"bakery"},"name":"K&U","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Der Beck":{"tags":{"name":"Der Beck","shop":"bakery"},"name":"Der Beck","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Thürmann":{"tags":{"name":"Thürmann","shop":"bakery"},"name":"Thürmann","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Backwerk":{"tags":{"name":"Backwerk","shop":"bakery"},"name":"Backwerk","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Schäfer's":{"tags":{"name":"Schäfer's","shop":"bakery"},"name":"Schäfer's","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Panaderia":{"tags":{"name":"Panaderia","shop":"bakery"},"name":"Panaderia","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Goeken backen":{"tags":{"name":"Goeken backen","shop":"bakery"},"name":"Goeken backen","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Stadtbäckerei Junge":{"tags":{"name":"Stadtbäckerei Junge","shop":"bakery"},"name":"Stadtbäckerei Junge","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Boulangerie Patisserie":{"tags":{"name":"Boulangerie Patisserie","shop":"bakery"},"name":"Boulangerie Patisserie","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Paul":{"tags":{"name":"Paul","shop":"bakery"},"name":"Paul","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Хлеб":{"tags":{"name":"Хлеб","shop":"bakery"},"name":"Хлеб","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Пекарня":{"tags":{"name":"Пекарня","shop":"bakery"},"name":"Пекарня","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Кулиничи":{"tags":{"name":"Кулиничи","shop":"bakery"},"name":"Кулиничи","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Sports Direct":{"tags":{"name":"Sports Direct","shop":"sports"},"name":"Sports Direct","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Decathlon":{"tags":{"name":"Decathlon","shop":"sports"},"name":"Decathlon","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Intersport":{"tags":{"name":"Intersport","shop":"sports"},"name":"Intersport","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Sports Authority":{"tags":{"name":"Sports Authority","shop":"sports"},"name":"Sports Authority","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Спортмастер":{"tags":{"name":"Спортмастер","shop":"sports"},"name":"Спортмастер","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Sport 2000":{"tags":{"name":"Sport 2000","shop":"sports"},"name":"Sport 2000","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Dick's Sporting Goods":{"tags":{"name":"Dick's Sporting Goods","shop":"sports"},"name":"Dick's Sporting Goods","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/Tedi":{"tags":{"name":"Tedi","shop":"variety_store"},"name":"Tedi","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/Dollarama":{"tags":{"name":"Dollarama","shop":"variety_store"},"name":"Dollarama","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/Family Dollar":{"tags":{"name":"Family Dollar","shop":"variety_store"},"name":"Family Dollar","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/Dollar Tree":{"tags":{"name":"Dollar Tree","shop":"variety_store"},"name":"Dollar Tree","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/pet/Fressnapf":{"tags":{"name":"Fressnapf","shop":"pet"},"name":"Fressnapf","icon":"dog-park","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/pet/PetSmart":{"tags":{"name":"PetSmart","shop":"pet"},"name":"PetSmart","icon":"dog-park","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/pet/Das Futterhaus":{"tags":{"name":"Das Futterhaus","shop":"pet"},"name":"Das Futterhaus","icon":"dog-park","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/pet/Pets at Home":{"tags":{"name":"Pets at Home","shop":"pet"},"name":"Pets at Home","icon":"dog-park","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/pet/Petco":{"tags":{"name":"Petco","shop":"pet"},"name":"Petco","icon":"dog-park","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/pet/Зоомагазин":{"tags":{"name":"Зоомагазин","shop":"pet"},"name":"Зоомагазин","icon":"dog-park","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Deichmann":{"tags":{"name":"Deichmann","shop":"shoes"},"name":"Deichmann","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Reno":{"tags":{"name":"Reno","shop":"shoes"},"name":"Reno","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Ecco":{"tags":{"name":"Ecco","shop":"shoes"},"name":"Ecco","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Clarks":{"tags":{"name":"Clarks","shop":"shoes"},"name":"Clarks","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/La Halle aux Chaussures":{"tags":{"name":"La Halle aux Chaussures","shop":"shoes"},"name":"La Halle aux Chaussures","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Brantano":{"tags":{"name":"Brantano","shop":"shoes"},"name":"Brantano","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Geox":{"tags":{"name":"Geox","shop":"shoes"},"name":"Geox","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Salamander":{"tags":{"name":"Salamander","shop":"shoes"},"name":"Salamander","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Обувь":{"tags":{"name":"Обувь","shop":"shoes"},"name":"Обувь","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Payless Shoe Source":{"tags":{"name":"Payless Shoe Source","shop":"shoes"},"name":"Payless Shoe Source","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Famous Footwear":{"tags":{"name":"Famous Footwear","shop":"shoes"},"name":"Famous Footwear","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Quick Schuh":{"tags":{"name":"Quick Schuh","shop":"shoes"},"name":"Quick Schuh","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Shoe Zone":{"tags":{"name":"Shoe Zone","shop":"shoes"},"name":"Shoe Zone","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Foot Locker":{"tags":{"name":"Foot Locker","shop":"shoes"},"name":"Foot Locker","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Bata":{"tags":{"name":"Bata","shop":"shoes"},"name":"Bata","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/ЦентрОбувь":{"tags":{"name":"ЦентрОбувь","shop":"shoes"},"name":"ЦентрОбувь","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/toys/La Grande Récré":{"tags":{"name":"La Grande Récré","shop":"toys"},"name":"La Grande Récré","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/toys/Toys R Us":{"tags":{"name":"Toys R Us","shop":"toys"},"name":"Toys R Us","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/toys/Intertoys":{"tags":{"name":"Intertoys","shop":"toys"},"name":"Intertoys","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/toys/Детский мир":{"tags":{"name":"Детский мир","shop":"toys"},"name":"Детский мир","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/toys/Игрушки":{"tags":{"name":"Игрушки","shop":"toys"},"name":"Игрушки","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/travel_agency/Flight Centre":{"tags":{"name":"Flight Centre","shop":"travel_agency"},"name":"Flight Centre","icon":"suitcase","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/travel_agency/Thomas Cook":{"tags":{"name":"Thomas Cook","shop":"travel_agency"},"name":"Thomas Cook","icon":"suitcase","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/jewelry/Bijou Brigitte":{"tags":{"name":"Bijou Brigitte","shop":"jewelry"},"name":"Bijou Brigitte","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/jewelry/Christ":{"tags":{"name":"Christ","shop":"jewelry"},"name":"Christ","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/jewelry/Swarovski":{"tags":{"name":"Swarovski","shop":"jewelry"},"name":"Swarovski","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Fielmann":{"tags":{"name":"Fielmann","shop":"optician"},"name":"Fielmann","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Apollo Optik":{"tags":{"name":"Apollo Optik","shop":"optician"},"name":"Apollo Optik","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Vision Express":{"tags":{"name":"Vision Express","shop":"optician"},"name":"Vision Express","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Оптика":{"tags":{"name":"Оптика","shop":"optician"},"name":"Оптика","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Optic 2000":{"tags":{"name":"Optic 2000","shop":"optician"},"name":"Optic 2000","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Alain Afflelou":{"tags":{"name":"Alain Afflelou","shop":"optician"},"name":"Alain Afflelou","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Specsavers":{"tags":{"name":"Specsavers","shop":"optician"},"name":"Specsavers","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Krys":{"tags":{"name":"Krys","shop":"optician"},"name":"Krys","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Atol":{"tags":{"name":"Atol","shop":"optician"},"name":"Atol","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/video/Blockbuster":{"tags":{"name":"Blockbuster","shop":"video"},"name":"Blockbuster","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/video/World of Video":{"tags":{"name":"World of Video","shop":"video"},"name":"World of Video","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Билайн":{"tags":{"name":"Билайн","shop":"mobile_phone"},"name":"Билайн","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/ソフトバンクショップ (SoftBank shop)":{"tags":{"name":"ソフトバンクショップ (SoftBank shop)","shop":"mobile_phone"},"name":"ソフトバンクショップ (SoftBank shop)","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Vodafone":{"tags":{"name":"Vodafone","shop":"mobile_phone"},"name":"Vodafone","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/O2":{"tags":{"name":"O2","shop":"mobile_phone"},"name":"O2","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Carphone Warehouse":{"tags":{"name":"Carphone Warehouse","shop":"mobile_phone"},"name":"Carphone Warehouse","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Orange":{"tags":{"name":"Orange","shop":"mobile_phone"},"name":"Orange","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Verizon Wireless":{"tags":{"name":"Verizon Wireless","shop":"mobile_phone"},"name":"Verizon Wireless","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Sprint":{"tags":{"name":"Sprint","shop":"mobile_phone"},"name":"Sprint","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/T-Mobile":{"tags":{"name":"T-Mobile","shop":"mobile_phone"},"name":"T-Mobile","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/МТС":{"tags":{"name":"МТС","shop":"mobile_phone"},"name":"МТС","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Евросеть":{"tags":{"name":"Евросеть","shop":"mobile_phone"},"name":"Евросеть","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Bell":{"tags":{"name":"Bell","shop":"mobile_phone"},"name":"Bell","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/The Phone House":{"tags":{"name":"The Phone House","shop":"mobile_phone"},"name":"The Phone House","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/SFR":{"tags":{"name":"SFR","shop":"mobile_phone"},"name":"SFR","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Связной":{"tags":{"name":"Связной","shop":"mobile_phone"},"name":"Связной","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Мегафон":{"tags":{"name":"Мегафон","shop":"mobile_phone"},"name":"Мегафон","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/AT&T":{"tags":{"name":"AT&T","shop":"mobile_phone"},"name":"AT&T","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/ドコモショップ (docomo shop)":{"tags":{"name":"ドコモショップ (docomo shop)","shop":"mobile_phone"},"name":"ドコモショップ (docomo shop)","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/au":{"tags":{"name":"au","shop":"mobile_phone"},"name":"au","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Movistar":{"tags":{"name":"Movistar","shop":"mobile_phone"},"name":"Movistar","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Bitė":{"tags":{"name":"Bitė","shop":"mobile_phone"},"name":"Bitė","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/computer/PC World":{"tags":{"name":"PC World","shop":"computer"},"name":"PC World","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/computer/DNS":{"tags":{"name":"DNS","shop":"computer"},"name":"DNS","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Klier":{"tags":{"name":"Klier","shop":"hairdresser"},"name":"Klier","icon":"hairdresser","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Supercuts":{"tags":{"name":"Supercuts","shop":"hairdresser"},"name":"Supercuts","icon":"hairdresser","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Hairkiller":{"tags":{"name":"Hairkiller","shop":"hairdresser"},"name":"Hairkiller","icon":"hairdresser","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Great Clips":{"tags":{"name":"Great Clips","shop":"hairdresser"},"name":"Great Clips","icon":"hairdresser","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Парикмахерская":{"tags":{"name":"Парикмахерская","shop":"hairdresser"},"name":"Парикмахерская","icon":"hairdresser","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Стиль":{"tags":{"name":"Стиль","shop":"hairdresser"},"name":"Стиль","icon":"hairdresser","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Franck Provost":{"tags":{"name":"Franck Provost","shop":"hairdresser"},"name":"Franck Provost","icon":"hairdresser","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Салон красоты":{"tags":{"name":"Салон красоты","shop":"hairdresser"},"name":"Салон красоты","icon":"hairdresser","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/hardware/1000 мелочей":{"tags":{"name":"1000 мелочей","shop":"hardware"},"name":"1000 мелочей","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/hardware/Хозтовары":{"tags":{"name":"Хозтовары","shop":"hardware"},"name":"Хозтовары","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/motorcycle/Yamaha":{"tags":{"name":"Yamaha","shop":"motorcycle"},"name":"Yamaha","icon":"scooter","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true}};
18964 var defaults = {"area":["category-landuse","category-building","category-water-area","leisure/park","amenity/hospital","amenity/place_of_worship","amenity/cafe","amenity/restaurant","area"],"line":["category-road","category-rail","category-path","category-water-line","category-barrier","power/line","line"],"point":["leisure/park","amenity/hospital","amenity/place_of_worship","amenity/cafe","amenity/restaurant","amenity/fast_food","amenity/bar","amenity/bank","shop/supermarket","point"],"vertex":["highway/crosswalk","highway/crossing","railway/level_crossing","highway/traffic_signals","highway/turning_circle","traffic_calming","highway/mini_roundabout","highway/motorway_junction","vertex"],"relation":["category-route","category-restriction","type/boundary","type/multipolygon","type/site","relation"]};
18966 var categories = {"category-barrier":{"geometry":"line","name":"Barrier Features","icon":"roadblock","members":["barrier/fence","barrier/wall","barrier/ditch","barrier/gate","barrier"]},"category-building":{"geometry":"area","name":"Building Features","icon":"building","members":["building","building/house","building/apartments","building/commercial","building/industrial","building/residential"]},"category-golf":{"geometry":"area","name":"Golf Features","icon":"golf","members":["golf/fairway","golf/green","golf/lateral_water_hazard_area","golf/rough","golf/bunker","golf/tee","golf/water_hazard_area"]},"category-landuse":{"geometry":"area","name":"Land Use Features","icon":"land-use","members":["landuse/residential","landuse/industrial","landuse/commercial","landuse/retail","landuse/farmland","landuse/farmyard","landuse/forest","landuse/meadow","landuse/cemetery","landuse/military"]},"category-path":{"geometry":"line","name":"Path Features","icon":"category-path","members":["highway/pedestrian","footway/crosswalk","footway/sidewalk","highway/steps","highway/path","highway/footway","highway/cycleway","highway/bridleway"]},"category-rail":{"geometry":"line","name":"Rail Features","icon":"category-rail","members":["railway/rail","railway/subway","railway/tram","railway/monorail","railway/disused","railway/abandoned"]},"category-restriction":{"geometry":"relation","name":"Restriction Features","icon":"restriction","members":["type/restriction/no_left_turn","type/restriction/no_right_turn","type/restriction/no_straight_on","type/restriction/no_u_turn","type/restriction/only_left_turn","type/restriction/only_right_turn","type/restriction/only_straight_on","type/restriction"]},"category-road":{"geometry":"line","name":"Road Features","icon":"category-roads","members":["highway/residential","highway/motorway","highway/trunk","highway/primary","highway/secondary","highway/tertiary","highway/unclassified","highway/service","highway/track","highway/motorway_link","highway/trunk_link","highway/primary_link","highway/secondary_link","highway/tertiary_link","highway/road"]},"category-route":{"geometry":"relation","name":"Route Features","icon":"route","members":["type/route/road","type/route/bicycle","type/route/foot","type/route/hiking","type/route/horse","type/route/bus","type/route/train","type/route/tram","type/route/ferry","type/route/power","type/route/pipeline","type/route/detour","type/route_master","type/route"]},"category-water-area":{"geometry":"area","name":"Water Features","icon":"water","members":["natural/water/lake","natural/water/pond","natural/water/reservoir","natural/water"]},"category-water-line":{"geometry":"line","name":"Water Features","icon":"category-water","members":["waterway/river","waterway/stream","waterway/canal","waterway/ditch","waterway/drain"]}};
18968 var fields = {"access_simple":{"key":"access","type":"combo","label":"Allowed Access","options":["permissive","private","customers","no"]},"access_toilets":{"key":"access","type":"combo","label":"Access","options":["yes","permissive","private","customers"]},"access":{"keys":["access","foot","motor_vehicle","bicycle","horse"],"reference":{"key":"access"},"type":"access","label":"Allowed Access","placeholder":"Not Specified","strings":{"types":{"access":"All","foot":"Foot","motor_vehicle":"Motor Vehicles","bicycle":"Bicycles","horse":"Horses"},"options":{"yes":{"title":"Allowed","description":"Access permitted by law; a right of way"},"no":{"title":"Prohibited","description":"Access not permitted to the general public"},"permissive":{"title":"Permissive","description":"Access permitted until such time as the owner revokes the permission"},"private":{"title":"Private","description":"Access permitted only with permission of the owner on an individual basis"},"designated":{"title":"Designated","description":"Access permitted according to signs or specific local laws"},"destination":{"title":"Destination","description":"Access permitted only to reach a destination"},"dismount":{"title":"Dismount","description":"Access permitted but rider must dismount"}}}},"address":{"type":"address","keys":["addr:city","addr:conscriptionnumber","addr:country","addr:district","addr:floor","addr:hamlet","addr:housename","addr:housenumber","addr:place","addr:postcode","addr:province","addr:state","addr:street","addr:subdistrict","addr:suburb"],"reference":{"key":"addr"},"icon":"address","universal":true,"label":"Address","strings":{"placeholders":{"city":"City","conscriptionnumber":"123","country":"Country","district":"District","floor":"Floor","hamlet":"Hamlet","housename":"Housename","housenumber":"123","place":"Place","postcode":"Postcode","province":"Province","state":"State","street":"Street","subdistrict":"Subdistrict","suburb":"Suburb"}}},"admin_level":{"key":"admin_level","type":"number","label":"Admin Level"},"aerialway":{"key":"aerialway","type":"typeCombo","label":"Type"},"aerialway/access":{"key":"aerialway:access","type":"combo","label":"Access","strings":{"options":{"entry":"Entry","exit":"Exit","both":"Both"}}},"aerialway/bubble":{"key":"aerialway:bubble","type":"check","label":"Bubble"},"aerialway/capacity":{"key":"aerialway:capacity","type":"number","label":"Capacity (per hour)","placeholder":"500, 2500, 5000..."},"aerialway/duration":{"key":"aerialway:duration","type":"number","label":"Duration (minutes)","placeholder":"1, 2, 3..."},"aerialway/heating":{"key":"aerialway:heating","type":"check","label":"Heated"},"aerialway/occupancy":{"key":"aerialway:occupancy","type":"number","label":"Occupancy","placeholder":"2, 4, 8..."},"aerialway/summer/access":{"key":"aerialway:summer:access","type":"combo","label":"Access (summer)","strings":{"options":{"entry":"Entry","exit":"Exit","both":"Both"}}},"aeroway":{"key":"aeroway","type":"typeCombo","label":"Type"},"amenity":{"key":"amenity","type":"typeCombo","label":"Type"},"area/highway":{"key":"area:highway","type":"typeCombo","label":"Type"},"artist":{"key":"artist_name","type":"text","label":"Artist"},"artwork_type":{"key":"artwork_type","type":"combo","label":"Type"},"atm":{"key":"atm","type":"check","label":"ATM"},"backrest":{"key":"backrest","type":"check","label":"Backrest"},"barrier":{"key":"barrier","type":"typeCombo","label":"Type"},"beauty":{"key":"beauty","type":"combo","label":"Shop Type"},"bench":{"key":"bench","type":"check","label":"Bench"},"bicycle_parking":{"key":"bicycle_parking","type":"combo","label":"Type"},"bin":{"key":"bin","type":"check","label":"Waste Bin"},"blood_components":{"key":"blood:","type":"multiCombo","label":"Blood Components","strings":{"options":{"whole":"whole blood","plasma":"plasma","platelets":"platelets","stemcells":"stem cell samples"}}},"board_type":{"key":"board_type","type":"typeCombo","label":"Type"},"boundary":{"key":"boundary","type":"combo","label":"Type"},"brand":{"key":"brand","type":"text","label":"Brand"},"building_area":{"key":"building","type":"combo","default":"yes","geometry":"area","label":"Building"},"building":{"key":"building","type":"combo","label":"Building"},"capacity":{"key":"capacity","type":"number","label":"Capacity","placeholder":"50, 100, 200..."},"cardinal_direction":{"key":"direction","type":"combo","label":"Direction","strings":{"options":{"N":"North","E":"East","S":"South","W":"West","NE":"Northeast","SE":"Southeast","SW":"Southwest","NW":"Northwest","NNE":"North-northeast","ENE":"East-northeast","ESE":"East-southeast","SSE":"South-southeast","SSW":"South-southwest","WSW":"West-southwest","WNW":"West-northwest","NNW":"North-northwest"}}},"clock_direction":{"key":"direction","type":"combo","label":"Direction","strings":{"options":{"clockwise":"Clockwise","anticlockwise":"Counterclockwise"}}},"collection_times":{"key":"collection_times","type":"text","label":"Collection Times"},"construction":{"key":"construction","type":"combo","label":"Type"},"content":{"key":"content","type":"combo","label":"Contents"},"country":{"key":"country","type":"combo","label":"Country"},"covered":{"key":"covered","type":"check","label":"Covered"},"craft":{"key":"craft","type":"typeCombo","label":"Type"},"crop":{"key":"crop","type":"combo","label":"Crop"},"crossing":{"key":"crossing","type":"combo","label":"Type"},"cuisine":{"key":"cuisine","type":"combo","label":"Cuisine"},"currency_multi":{"key":"currency:","type":"multiCombo","label":"Currency Types"},"cycle_network":{"key":"cycle_network","type":"networkCombo","label":"Network"},"cycleway":{"keys":["cycleway:left","cycleway:right"],"reference":{"key":"cycleway"},"type":"cycleway","label":"Bike Lanes","placeholder":"none","strings":{"types":{"cycleway:left":"Left side","cycleway:right":"Right side"},"options":{"none":{"title":"None","description":"No bike lane"},"lane":{"title":"Standard bike lane","description":"A bike lane separated from auto traffic by a painted line"},"shared_lane":{"title":"Shared bike lane","description":"A bike lane with no separation from auto traffic"},"track":{"title":"Bike track","description":"A bike lane separated from traffic by a physical barrier"},"share_busway":{"title":"Bike lane shared with bus","description":"A bike lane shared with a bus lane"},"opposite_lane":{"title":"Opposite bike lane","description":"A bike lane that travels in the opposite direction of traffic"},"opposite":{"title":"Contraflow bike lane","description":"A bike lane that travels in both directions on a one-way street"}}}},"date":{"key":"date","type":"check","label":"Date"},"delivery":{"key":"delivery","type":"check","label":"Delivery"},"denomination":{"key":"denomination","type":"combo","label":"Denomination"},"denotation":{"key":"denotation","type":"combo","label":"Denotation"},"description":{"key":"description","type":"textarea","label":"Description","universal":true},"diaper":{"key":"diaper","type":"combo","label":"Diaper Changing Available","options":["yes","no","room","1","2","3","4","5"]},"display":{"key":"display","type":"combo","label":"Display","options":["analog","digital","sundial","unorthodox"]},"dock":{"key":"dock","type":"combo","label":"Type"},"drive_through":{"key":"drive_through","type":"check","label":"Drive-Through"},"electrified":{"key":"electrified","type":"combo","label":"Electrification","placeholder":"Contact Line, Electrified Rail...","strings":{"options":{"contact_line":"Contact Line","rail":"Electrified Rail","yes":"Yes (unspecified)","no":"No"}}},"elevation":{"key":"ele","type":"number","icon":"elevation","universal":true,"label":"Elevation"},"emergency":{"key":"emergency","type":"check","label":"Emergency"},"entrance":{"key":"entrance","type":"typeCombo","label":"Type"},"except":{"key":"except","type":"combo","label":"Exceptions"},"fax":{"key":"fax","type":"tel","label":"Fax","placeholder":"+31 42 123 4567"},"fee":{"key":"fee","type":"check","label":"Fee"},"fire_hydrant/type":{"key":"fire_hydrant:type","type":"combo","label":"Type","strings":{"options":{"pillar":"Pillar/Aboveground","underground":"Underground","wall":"Wall","pond":"Pond"}}},"fixme":{"key":"fixme","type":"textarea","label":"Fix Me","universal":true},"fuel_multi":{"key":"fuel:","type":"multiCombo","label":"Fuel Types"},"fuel":{"key":"fuel","type":"combo","label":"Fuel"},"gauge":{"key":"gauge","type":"combo","label":"Gauge"},"gender":{"type":"radio","keys":["male","female","unisex"],"label":"Gender","placeholder":"Unknown","strings":{"options":{"male":"Male","female":"Female","unisex":"Unisex"}}},"generator/method":{"key":"generator:method","type":"combo","label":"Method"},"generator/source":{"key":"generator:source","type":"combo","label":"Source"},"generator/type":{"key":"generator:type","type":"combo","label":"Type"},"golf_hole":{"key":"ref","type":"text","label":"Reference","placeholder":"Hole number (1-18)"},"handicap":{"key":"handicap","type":"number","label":"Handicap","placeholder":"1-18"},"handrail":{"key":"handrail","type":"check","label":"Handrail"},"height":{"key":"height","type":"number","label":"Height (meters)"},"highway":{"key":"highway","type":"typeCombo","label":"Type"},"historic":{"key":"historic","type":"typeCombo","label":"Type"},"hoops":{"key":"hoops","type":"number","label":"Hoops","placeholder":"1, 2, 4..."},"iata":{"key":"iata","type":"text","label":"IATA"},"icao":{"key":"icao","type":"text","label":"ICAO"},"incline_steps":{"key":"incline","type":"combo","label":"Incline","strings":{"options":{"up":"Up","down":"Down"}}},"incline":{"key":"incline","type":"combo","label":"Incline"},"indoor":{"key":"indoor","type":"check","label":"Indoor"},"information":{"key":"information","type":"typeCombo","label":"Type"},"internet_access":{"key":"internet_access","type":"combo","label":"Internet Access","strings":{"options":{"yes":"Yes","no":"No","wlan":"Wifi","wired":"Wired","terminal":"Terminal"}}},"internet_access/fee":{"key":"internet_access:fee","type":"check","label":"Internet Access Fee"},"kerb":{"key":"kerb","type":"combo","label":"Curb Ramp"},"lamp_type":{"key":"lamp_type","type":"combo","label":"Type"},"landuse":{"key":"landuse","type":"typeCombo","label":"Type"},"lanes":{"key":"lanes","type":"number","label":"Lanes","placeholder":"1, 2, 3..."},"layer":{"key":"layer","type":"combo","label":"Layer"},"leaf_cycle_singular":{"key":"leaf_cycle","type":"combo","label":"Leaf Cycle","strings":{"options":{"evergreen":"Evergreen","deciduous":"Deciduous","semi_evergreen":"Semi-Evergreen","semi_deciduous":"Semi-Deciduous"}}},"leaf_cycle":{"key":"leaf_cycle","type":"combo","label":"Leaf Cycle","strings":{"options":{"evergreen":"Evergreen","deciduous":"Deciduous","semi_evergreen":"Semi-Evergreen","semi_deciduous":"Semi-Deciduous","mixed":"Mixed"}}},"leaf_type_singular":{"key":"leaf_type","type":"combo","label":"Leaf Type","strings":{"options":{"broadleaved":"Broadleaved","needleleaved":"Needleleaved","leafless":"Leafless"}}},"leaf_type":{"key":"leaf_type","type":"combo","label":"Leaf Type","strings":{"options":{"broadleaved":"Broadleaved","needleleaved":"Needleleaved","mixed":"Mixed","leafless":"Leafless"}}},"leisure":{"key":"leisure","type":"typeCombo","label":"Type"},"length":{"key":"length","type":"number","label":"Length (Meters)"},"level":{"key":"level","type":"combo","label":"Level","universal":true},"levels":{"key":"building:levels","type":"number","label":"Levels","placeholder":"2, 4, 6..."},"lit":{"key":"lit","type":"check","label":"Lit"},"location":{"key":"location","type":"combo","label":"Location"},"man_made":{"key":"man_made","type":"typeCombo","label":"Type"},"map_size":{"key":"map_size","type":"typeCombo","label":"Coverage"},"map_type":{"key":"map_type","type":"typeCombo","label":"Type"},"maxspeed":{"key":"maxspeed","type":"maxspeed","label":"Speed Limit","placeholder":"40, 50, 60..."},"maxstay":{"key":"maxstay","type":"combo","label":"Max Stay","options":["15 min","30 min","45 min","1 hr","1.5 hr","2 hr","2.5 hr","3 hr","4 hr","1 day","2 day"],"snake_case":false},"mtb/scale":{"key":"mtb:scale","type":"combo","label":"Mountain Biking Difficulty","placeholder":"0, 1, 2, 3...","strings":{"options":{"0":"0: Solid gravel/packed earth, no obstacles, wide curves","1":"1: Some loose surface, small obstacles, wide curves","2":"2: Much loose surface, large obstacles, easy hairpins","3":"3: Slippery surface, large obstacles, tight hairpins","4":"4: Loose surface or boulders, dangerous hairpins","5":"5: Maximum difficulty, boulder fields, landslides","6":"6: Not rideable except by the very best mountain bikers"}}},"mtb/scale/imba":{"key":"mtb:scale:imba","type":"combo","label":"IMBA Trail Difficulty","placeholder":"Easy, Medium, Difficult...","strings":{"options":{"0":"Easiest (white circle)","1":"Easy (green circle)","2":"Medium (blue square)","3":"Difficult (black diamond)","4":"Extremely Difficult (double black diamond)"}}},"mtb/scale/uphill":{"key":"mtb:scale:uphill","type":"combo","label":"Mountain Biking Uphill Difficulty","placeholder":"0, 1, 2, 3...","strings":{"options":{"0":"0: Avg. incline <10%, gravel/packed earth, no obstacles","1":"1: Avg. incline <15%, gravel/packed earth, few small objects","2":"2: Avg. incline <20%, stable surface, fistsize rocks/roots","3":"3: Avg. incline <25%, variable surface, fistsize rocks/branches","4":"4: Avg. incline <30%, poor condition, big rocks/branches","5":"5: Very steep, bike generally needs to be pushed or carried"}}},"name":{"key":"name","type":"localized","label":"Name","placeholder":"Common name (if any)"},"natural":{"key":"natural","type":"typeCombo","label":"Natural"},"network_bicycle":{"key":"network","type":"combo","label":"Network Type","placeholder":"Local, Regional, National, International","strings":{"options":{"lcn":"Local","rcn":"Regional","ncn":"National","icn":"International"}}},"network_foot":{"key":"network","type":"combo","label":"Network Type","placeholder":"Local, Regional, National, International","strings":{"options":{"lwn":"Local","rwn":"Regional","nwn":"National","iwn":"International"}}},"network_horse":{"key":"network","type":"combo","label":"Network Type","placeholder":"Local, Regional, National, International","strings":{"options":{"lhn":"Local","rhn":"Regional","nhn":"National","ihn":"International"}}},"network_road":{"key":"network","type":"networkCombo","label":"Network"},"network":{"key":"network","type":"text","label":"Network"},"note":{"key":"note","type":"textarea","universal":true,"icon":"note","label":"Note"},"office":{"key":"office","type":"typeCombo","label":"Type"},"oneway_yes":{"key":"oneway","type":"check","label":"One Way","strings":{"options":{"undefined":"Assumed to be Yes","yes":"Yes","no":"No"}}},"oneway":{"key":"oneway","type":"check","label":"One Way","strings":{"options":{"undefined":"Assumed to be No","yes":"Yes","no":"No"}}},"opening_hours":{"key":"opening_hours","type":"text","label":"Hours"},"operator":{"key":"operator","type":"text","label":"Operator"},"par":{"key":"par","type":"number","label":"Par","placeholder":"3, 4, 5..."},"parallel_direction":{"key":"direction","type":"combo","label":"Direction","strings":{"options":{"forward":"Forward","backward":"Backward"}}},"park_ride":{"key":"park_ride","type":"check","label":"Park and Ride"},"parking":{"key":"parking","type":"combo","label":"Type","strings":{"options":{"surface":"Surface","multi-storey":"Multilevel","underground":"Underground","sheds":"Sheds","carports":"Carports","garage_boxes":"Garage Boxes","lane":"Roadside Lane"}}},"payment_multi":{"key":"payment:","type":"multiCombo","label":"Payment Types"},"phone":{"key":"phone","type":"tel","icon":"telephone","universal":true,"label":"Phone","placeholder":"+31 42 123 4567"},"piste/difficulty":{"key":"piste:difficulty","type":"combo","label":"Difficulty","placeholder":"Easy, Intermediate, Advanced...","strings":{"options":{"novice":"Novice (instructional)","easy":"Easy (green circle)","intermediate":"Intermediate (blue square)","advanced":"Advanced (black diamond)","expert":"Expert (double black diamond)","freeride":"Freeride (off-piste)","extreme":"Extreme (climbing equipment required)"}}},"piste/grooming":{"key":"piste:grooming","type":"combo","label":"Grooming","strings":{"options":{"classic":"Classic","mogul":"Mogul","backcountry":"Backcountry","classic+skating":"Classic and Skating","scooter":"Scooter/Snowmobile","skating":"Skating"}}},"piste/type":{"key":"piste:type","type":"typeCombo","label":"Type","strings":{"options":{"downhill":"Downhill","nordic":"Nordic","skitour":"Skitour","sled":"Sled","hike":"Hike","sleigh":"Sleigh","ice_skate":"Ice Skate","snow_park":"Snow Park","playground":"Playground"}}},"place":{"key":"place","type":"typeCombo","label":"Type"},"population":{"key":"population","type":"text","label":"Population"},"power_supply":{"key":"power_supply","type":"check","label":"Power Supply"},"power":{"key":"power","type":"typeCombo","label":"Type"},"railway":{"key":"railway","type":"typeCombo","label":"Type"},"recycling_accepts":{"key":"recycling:","type":"multiCombo","label":"Accepts"},"recycling_type":{"key":"recycling_type","default":"container","type":"combo","label":"Recycling Type","strings":{"options":{"container":"Container","centre":"Recycling Center"}}},"ref":{"key":"ref","type":"text","label":"Reference"},"relation":{"key":"type","type":"combo","label":"Type"},"religion":{"key":"religion","type":"combo","label":"Religion"},"restriction":{"key":"restriction","type":"combo","label":"Type"},"restrictions":{"type":"restrictions","geometry":"vertex","icon":"restrictions","reference":{"rtype":"restriction"},"label":"Turn Restrictions"},"rooms":{"key":"rooms","type":"number","label":"Rooms"},"route_master":{"key":"route_master","type":"combo","label":"Type"},"route":{"key":"route","type":"combo","label":"Type"},"sac_scale":{"key":"sac_scale","type":"combo","label":"Hiking Difficulty","placeholder":"Mountain Hiking, Alpine Hiking...","strings":{"options":{"hiking":"T1: Hiking","mountain_hiking":"T2: Mountain Hiking","demanding_mountain_hiking":"T3: Demanding Mountain Hiking","alpine_hiking":"T4: Alpine Hiking","demanding_alpine_hiking":"T5: Demanding Alpine Hiking","difficult_alpine_hiking":"T6: Difficult Alpine Hiking"}}},"sanitary_dump_station":{"key":"sanitary_dump_station","type":"check","label":"Toilet Disposal"},"seasonal":{"key":"seasonal","type":"check","label":"Seasonal"},"second_hand":{"key":"second_hand","type":"combo","label":"Sells Used","placeholder":"Yes, No, Only","strings":{"options":{"yes":"Yes","no":"No","only":"Only"}}},"service_rail":{"key":"service","type":"combo","label":"Service Type","strings":{"options":{"spur":"Spur","yard":"Yard","siding":"Siding","crossover":"Crossover"}}},"service":{"key":"service","type":"combo","label":"Type","options":["parking_aisle","driveway","alley","emergency_access","drive-through"]},"service/bicycle":{"key":"service:bicycle:","type":"multiCombo","label":"Services"},"shelter_type":{"key":"shelter_type","type":"combo","label":"Type"},"shelter":{"key":"shelter","type":"check","label":"Shelter"},"shop":{"key":"shop","type":"typeCombo","label":"Type"},"site":{"key":"site","type":"combo","label":"Type"},"smoking":{"key":"smoking","type":"combo","label":"Smoking","placeholder":"No, Separated, Yes...","strings":{"options":{"no":"No smoking anywhere","separated":"In smoking areas, not physically isolated","isolated":"In smoking areas, physically isolated","outside":"Allowed outside","yes":"Allowed everywhere","dedicated":"Dedicated to smokers (e.g. smokers' club)"}}},"smoothness":{"key":"smoothness","type":"combo","label":"Smoothness","placeholder":"Thin Rollers, Wheels, Off-Road...","strings":{"options":{"excellent":"Thin Rollers: rollerblade, skateboard","good":"Thin Wheels: racing bike","intermediate":"Wheels: city bike, wheelchair, scooter","bad":"Robust Wheels: trekking bike, car, rickshaw","very_bad":"High Clearance: light duty off-road vehicle","horrible":"Off-Road: heavy duty off-road vehicle","very_horrible":"Specialized off-road: tractor, ATV","impassable":"Impassable / No wheeled vehicle"}}},"social_facility_for":{"key":"social_facility:for","type":"radio","label":"People served","placeholder":"Homeless, Disabled, Child, etc","options":["abused","child","disabled","diseased","drug_addicted","homeless","juvenile","mental_health","migrant","orphan","senior","underprivileged","unemployed","victim"]},"source":{"key":"source","type":"text","icon":"source","universal":true,"label":"Source"},"sport_ice":{"key":"sport","type":"combo","label":"Sport","options":["skating","hockey","multi","curling","ice_stock"]},"sport_racing":{"key":"sport","type":"combo","label":"Sport","options":["cycling","dog_racing","horse_racing","karting","motor","motocross","running"]},"sport":{"key":"sport","type":"combo","label":"Sport"},"stars":{"key":"stars","type":"number","label":"Stars"},"stop":{"key":"stop","type":"combo","label":"Stop Type","strings":{"options":{"all":"All Ways","minor":"Minor Road"}}},"structure":{"type":"radio","keys":["bridge","tunnel","embankment","cutting","ford"],"label":"Structure","placeholder":"Unknown","strings":{"options":{"bridge":"Bridge","tunnel":"Tunnel","embankment":"Embankment","cutting":"Cutting","ford":"Ford"}}},"studio":{"key":"studio","type":"combo","label":"Type"},"substation":{"key":"substation","type":"typeCombo","label":"Type"},"supervised":{"key":"supervised","type":"check","label":"Supervised"},"support":{"key":"support","type":"combo","label":"Support"},"surface":{"key":"surface","type":"combo","label":"Surface"},"tactile_paving":{"key":"tactile_paving","type":"check","label":"Tactile Paving"},"takeaway":{"key":"takeaway","type":"combo","label":"Takeaway","placeholder":"Yes, No, Takeaway Only...","strings":{"options":{"yes":"Yes","no":"No","only":"Takeaway Only"}}},"toilets/disposal":{"key":"toilets:disposal","type":"combo","label":"Disposal","strings":{"options":{"flush":"Flush","pitlatrine":"Pit/Latrine","chemical":"Chemical","bucket":"Bucket"}}},"tourism":{"key":"tourism","type":"typeCombo","label":"Type"},"tower/construction":{"key":"tower:construction","type":"combo","label":"Construction","placeholder":"Guyed, Lattice, Concealed, ..."},"tower/type":{"key":"tower:type","type":"combo","label":"Type"},"tracktype":{"key":"tracktype","type":"combo","label":"Track Type","placeholder":"Solid, Mostly Solid, Soft...","strings":{"options":{"grade1":"Solid: paved or heavily compacted hardcore surface","grade2":"Mostly Solid: gravel/rock with some soft material mixed in","grade3":"Even mixture of hard and soft materials","grade4":"Mostly Soft: soil/sand/grass with some hard material mixed in","grade5":"Soft: soil/sand/grass"}}},"traffic_calming":{"key":"traffic_calming","type":"typeCombo","label":"Type"},"traffic_signals":{"key":"traffic_signals","type":"combo","label":"Type","default":"signal"},"trail_visibility":{"key":"trail_visibility","type":"combo","label":"Trail Visibility","placeholder":"Excellent, Good, Bad...","strings":{"options":{"excellent":"Excellent: unambiguous path or markers everywhere","good":"Good: markers visible, sometimes require searching","intermediate":"Intermediate: few markers, path mostly visible","bad":"Bad: no markers, path sometimes invisible/pathless","horrible":"Horrible: often pathless, some orientation skills required","no":"No: pathless, excellent orientation skills required"}}},"trees":{"key":"trees","type":"combo","label":"Trees"},"tunnel":{"key":"tunnel","type":"combo","label":"Tunnel"},"vending":{"key":"vending","type":"combo","label":"Type of Goods"},"visibility":{"key":"visibility","type":"combo","label":"Visibility","strings":{"options":{"house":"Up to 5m (16ft)","street":"5 to 20m (16 to 65ft)","area":"Over 20m (65ft)"}}},"water_point":{"key":"water_point","type":"check","label":"Water Point"},"water":{"key":"water","type":"combo","label":"Type"},"waterway":{"key":"waterway","type":"typeCombo","label":"Type"},"website":{"key":"website","type":"url","icon":"website","placeholder":"http://example.com/","universal":true,"label":"Website"},"wetland":{"key":"wetland","type":"combo","label":"Type"},"wheelchair":{"key":"wheelchair","type":"radio","options":["yes","limited","no"],"icon":"wheelchair","universal":true,"label":"Wheelchair Access"},"width":{"key":"width","type":"number","label":"Width (Meters)"},"wikipedia":{"key":"wikipedia","keys":["wikipedia","wikidata"],"type":"wikipedia","icon":"wikipedia","universal":true,"label":"Wikipedia"}};
18971 imagery: dataImagery,
18974 defaults: defaults,
18975 categories: categories,
18980 function osmEntity$$1(attrs) {
18981 // For prototypal inheritance.
18982 if (this instanceof osmEntity$$1) return;
18984 // Create the appropriate subtype.
18985 if (attrs && attrs.type) {
18986 return osmEntity$$1[attrs.type].apply(this, arguments);
18987 } else if (attrs && attrs.id) {
18988 return osmEntity$$1[osmEntity$$1.id.type(attrs.id)].apply(this, arguments);
18991 // Initialize a generic Entity (used only in tests).
18992 return (new osmEntity$$1()).initialize(arguments);
18996 osmEntity$$1.id = function(type) {
18997 return osmEntity$$1.id.fromOSM(type, osmEntity$$1.id.next[type]--);
19001 osmEntity$$1.id.next = {
19002 node: -1, way: -1, relation: -1
19006 osmEntity$$1.id.fromOSM = function(type, id) {
19007 return type[0] + id;
19011 osmEntity$$1.id.toOSM = function(id) {
19012 return id.slice(1);
19016 osmEntity$$1.id.type = function(id) {
19017 return { 'n': 'node', 'w': 'way', 'r': 'relation' }[id[0]];
19021 // A function suitable for use as the second argument to d3.selection#data().
19022 osmEntity$$1.key = function(entity) {
19023 return entity.id + 'v' + (entity.v || 0);
19027 osmEntity$$1.prototype = {
19032 initialize: function(sources) {
19033 for (var i = 0; i < sources.length; ++i) {
19034 var source = sources[i];
19035 for (var prop in source) {
19036 if (Object.prototype.hasOwnProperty.call(source, prop)) {
19037 if (source[prop] === undefined) {
19040 this[prop] = source[prop];
19046 if (!this.id && this.type) {
19047 this.id = osmEntity$$1.id(this.type);
19049 if (!this.hasOwnProperty('visible')) {
19050 this.visible = true;
19054 Object.freeze(this);
19055 Object.freeze(this.tags);
19057 if (this.loc) Object.freeze(this.loc);
19058 if (this.nodes) Object.freeze(this.nodes);
19059 if (this.members) Object.freeze(this.members);
19066 copy: function(resolver, copies) {
19067 if (copies[this.id])
19068 return copies[this.id];
19070 var copy = osmEntity$$1(this, {id: undefined, user: undefined, version: undefined});
19071 copies[this.id] = copy;
19077 osmId: function() {
19078 return osmEntity$$1.id.toOSM(this.id);
19082 isNew: function() {
19083 return this.osmId() < 0;
19087 update: function(attrs) {
19088 return osmEntity$$1(this, attrs, {v: 1 + (this.v || 0)});
19092 mergeTags: function(tags) {
19093 var merged = lodash.clone(this.tags), changed = false;
19094 for (var k in tags) {
19095 var t1 = merged[k],
19100 } else if (t1 !== t2) {
19102 merged[k] = lodash.union(t1.split(/;\s*/), t2.split(/;\s*/)).join(';');
19105 return changed ? this.update({tags: merged}) : this;
19109 intersects: function(extent, resolver) {
19110 return this.extent(resolver).intersects(extent);
19114 isUsed: function(resolver) {
19115 return lodash.without(Object.keys(this.tags), 'area').length > 0 ||
19116 resolver.parentRelations(this).length > 0;
19120 hasInterestingTags: function() {
19121 return lodash.keys(this.tags).some(osmIsInterestingTag);
19125 isHighwayIntersection: function() {
19130 deprecatedTags: function() {
19131 var tags = lodash.toPairs(this.tags);
19132 var deprecated = {};
19134 dataDeprecated.forEach(function(d) {
19135 var match = lodash.toPairs(d.old)[0];
19136 tags.forEach(function(t) {
19137 if (t[0] === match[0] &&
19138 (t[1] === match[1] || match[1] === '*')) {
19139 deprecated[t[0]] = t[1];
19148 function geoExtent$$1(min, max) {
19149 if (!(this instanceof geoExtent$$1)) return new geoExtent$$1(min, max);
19150 if (min instanceof geoExtent$$1) {
19152 } else if (min && min.length === 2 && min[0].length === 2 && min[1].length === 2) {
19156 this[0] = min || [ Infinity, Infinity];
19157 this[1] = max || min || [-Infinity, -Infinity];
19161 geoExtent$$1.prototype = new Array(2);
19163 lodash.extend(geoExtent$$1.prototype, {
19165 equals: function (obj) {
19166 return this[0][0] === obj[0][0] &&
19167 this[0][1] === obj[0][1] &&
19168 this[1][0] === obj[1][0] &&
19169 this[1][1] === obj[1][1];
19173 extend: function(obj) {
19174 if (!(obj instanceof geoExtent$$1)) obj = new geoExtent$$1(obj);
19175 return geoExtent$$1(
19176 [Math.min(obj[0][0], this[0][0]), Math.min(obj[0][1], this[0][1])],
19177 [Math.max(obj[1][0], this[1][0]), Math.max(obj[1][1], this[1][1])]
19182 _extend: function(extent) {
19183 this[0][0] = Math.min(extent[0][0], this[0][0]);
19184 this[0][1] = Math.min(extent[0][1], this[0][1]);
19185 this[1][0] = Math.max(extent[1][0], this[1][0]);
19186 this[1][1] = Math.max(extent[1][1], this[1][1]);
19191 return Math.abs((this[1][0] - this[0][0]) * (this[1][1] - this[0][1]));
19195 center: function() {
19196 return [(this[0][0] + this[1][0]) / 2,
19197 (this[0][1] + this[1][1]) / 2];
19201 rectangle: function() {
19202 return [this[0][0], this[0][1], this[1][0], this[1][1]];
19207 return { minX: this[0][0], minY: this[0][1], maxX: this[1][0], maxY: this[1][1] };
19211 polygon: function() {
19213 [this[0][0], this[0][1]],
19214 [this[0][0], this[1][1]],
19215 [this[1][0], this[1][1]],
19216 [this[1][0], this[0][1]],
19217 [this[0][0], this[0][1]]
19222 contains: function(obj) {
19223 if (!(obj instanceof geoExtent$$1)) obj = new geoExtent$$1(obj);
19224 return obj[0][0] >= this[0][0] &&
19225 obj[0][1] >= this[0][1] &&
19226 obj[1][0] <= this[1][0] &&
19227 obj[1][1] <= this[1][1];
19231 intersects: function(obj) {
19232 if (!(obj instanceof geoExtent$$1)) obj = new geoExtent$$1(obj);
19233 return obj[0][0] <= this[1][0] &&
19234 obj[0][1] <= this[1][1] &&
19235 obj[1][0] >= this[0][0] &&
19236 obj[1][1] >= this[0][1];
19240 intersection: function(obj) {
19241 if (!this.intersects(obj)) return new geoExtent$$1();
19242 return new geoExtent$$1(
19243 [Math.max(obj[0][0], this[0][0]), Math.max(obj[0][1], this[0][1])],
19244 [Math.min(obj[1][0], this[1][0]), Math.min(obj[1][1], this[1][1])]
19249 percentContainedIn: function(obj) {
19250 if (!(obj instanceof geoExtent$$1)) obj = new geoExtent$$1(obj);
19251 var a1 = this.intersection(obj).area(),
19254 if (a1 === Infinity || a2 === Infinity || a1 === 0 || a2 === 0) {
19262 padByMeters: function(meters) {
19263 var dLat = geoMetersToLat(meters),
19264 dLon = geoMetersToLon(meters, this.center()[1]);
19265 return geoExtent$$1(
19266 [this[0][0] - dLon, this[0][1] - dLat],
19267 [this[1][0] + dLon, this[1][1] + dLat]
19272 toParam: function() {
19273 return this.rectangle().join(',');
19278 var version = "4.3.0";
19280 var ascending = function(a, b) {
19281 return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
19284 var bisector = function(compare) {
19285 if (compare.length === 1) compare = ascendingComparator(compare);
19287 left: function(a, x, lo, hi) {
19288 if (lo == null) lo = 0;
19289 if (hi == null) hi = a.length;
19291 var mid = lo + hi >>> 1;
19292 if (compare(a[mid], x) < 0) lo = mid + 1;
19297 right: function(a, x, lo, hi) {
19298 if (lo == null) lo = 0;
19299 if (hi == null) hi = a.length;
19301 var mid = lo + hi >>> 1;
19302 if (compare(a[mid], x) > 0) hi = mid;
19310 function ascendingComparator(f) {
19311 return function(d, x) {
19312 return ascending(f(d), x);
19316 var ascendingBisect = bisector(ascending);
19317 var bisectRight = ascendingBisect.right;
19318 var bisectLeft = ascendingBisect.left;
19320 var descending = function(a, b) {
19321 return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
19324 var number = function(x) {
19325 return x === null ? NaN : +x;
19328 var variance = function(array, f) {
19329 var n = array.length,
19339 if (!isNaN(a = number(array[i]))) {
19349 if (!isNaN(a = number(f(array[i], i, array)))) {
19357 if (j > 1) return s / (j - 1);
19360 var deviation = function(array, f) {
19361 var v = variance(array, f);
19362 return v ? Math.sqrt(v) : v;
19365 var extent = function(array, f) {
19373 while (++i < n) if ((b = array[i]) != null && b >= b) { a = c = b; break; }
19374 while (++i < n) if ((b = array[i]) != null) {
19381 while (++i < n) if ((b = f(array[i], i, array)) != null && b >= b) { a = c = b; break; }
19382 while (++i < n) if ((b = f(array[i], i, array)) != null) {
19391 var array = Array.prototype;
19393 var slice = array.slice;
19394 var map = array.map;
19396 var constant$1 = function(x) {
19397 return function() {
19402 var identity = function(x) {
19406 var range = function(start, stop, step) {
19407 start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step;
19410 n = Math.max(0, Math.ceil((stop - start) / step)) | 0,
19411 range = new Array(n);
19414 range[i] = start + i * step;
19420 var e10 = Math.sqrt(50);
19421 var e5 = Math.sqrt(10);
19422 var e2 = Math.sqrt(2);
19424 var ticks = function(start, stop, count) {
19425 var step = tickStep(start, stop, count);
19427 Math.ceil(start / step) * step,
19428 Math.floor(stop / step) * step + step / 2, // inclusive
19433 function tickStep(start, stop, count) {
19434 var step0 = Math.abs(stop - start) / Math.max(0, count),
19435 step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),
19436 error = step0 / step1;
19437 if (error >= e10) step1 *= 10;
19438 else if (error >= e5) step1 *= 5;
19439 else if (error >= e2) step1 *= 2;
19440 return stop < start ? -step1 : step1;
19443 var sturges = function(values) {
19444 return Math.ceil(Math.log(values.length) / Math.LN2) + 1;
19447 var histogram = function() {
19448 var value = identity,
19450 threshold = sturges;
19452 function histogram(data) {
19456 values = new Array(n);
19458 for (i = 0; i < n; ++i) {
19459 values[i] = value(data[i], i, data);
19462 var xz = domain(values),
19465 tz = threshold(values, x0, x1);
19467 // Convert number of thresholds into uniform thresholds.
19468 if (!Array.isArray(tz)) tz = ticks(x0, x1, tz);
19470 // Remove any thresholds outside the domain.
19472 while (tz[0] <= x0) tz.shift(), --m;
19473 while (tz[m - 1] >= x1) tz.pop(), --m;
19475 var bins = new Array(m + 1),
19478 // Initialize bins.
19479 for (i = 0; i <= m; ++i) {
19480 bin = bins[i] = [];
19481 bin.x0 = i > 0 ? tz[i - 1] : x0;
19482 bin.x1 = i < m ? tz[i] : x1;
19485 // Assign data to bins by value, ignoring any outside the domain.
19486 for (i = 0; i < n; ++i) {
19488 if (x0 <= x && x <= x1) {
19489 bins[bisectRight(tz, x, 0, m)].push(data[i]);
19496 histogram.value = function(_) {
19497 return arguments.length ? (value = typeof _ === "function" ? _ : constant$1(_), histogram) : value;
19500 histogram.domain = function(_) {
19501 return arguments.length ? (domain = typeof _ === "function" ? _ : constant$1([_[0], _[1]]), histogram) : domain;
19504 histogram.thresholds = function(_) {
19505 return arguments.length ? (threshold = typeof _ === "function" ? _ : Array.isArray(_) ? constant$1(slice.call(_)) : constant$1(_), histogram) : threshold;
19511 var threshold = function(array, p, f) {
19512 if (f == null) f = number;
19513 if (!(n = array.length)) return;
19514 if ((p = +p) <= 0 || n < 2) return +f(array[0], 0, array);
19515 if (p >= 1) return +f(array[n - 1], n - 1, array);
19519 a = +f(array[i], i, array),
19520 b = +f(array[i + 1], i + 1, array);
19521 return a + (b - a) * (h - i);
19524 var freedmanDiaconis = function(values, min, max) {
19525 values = map.call(values, number).sort(ascending);
19526 return Math.ceil((max - min) / (2 * (threshold(values, 0.75) - threshold(values, 0.25)) * Math.pow(values.length, -1 / 3)));
19529 var scott = function(values, min, max) {
19530 return Math.ceil((max - min) / (3.5 * deviation(values) * Math.pow(values.length, -1 / 3)));
19533 var max = function(array, f) {
19540 while (++i < n) if ((b = array[i]) != null && b >= b) { a = b; break; }
19541 while (++i < n) if ((b = array[i]) != null && b > a) a = b;
19545 while (++i < n) if ((b = f(array[i], i, array)) != null && b >= b) { a = b; break; }
19546 while (++i < n) if ((b = f(array[i], i, array)) != null && b > a) a = b;
19552 var mean = function(array, f) {
19560 while (++i < n) if (!isNaN(a = number(array[i]))) s += a; else --j;
19564 while (++i < n) if (!isNaN(a = number(f(array[i], i, array)))) s += a; else --j;
19567 if (j) return s / j;
19570 var median = function(array, f) {
19577 while (++i < n) if (!isNaN(a = number(array[i]))) numbers.push(a);
19581 while (++i < n) if (!isNaN(a = number(f(array[i], i, array)))) numbers.push(a);
19584 return threshold(numbers.sort(ascending), 0.5);
19587 var merge = function(arrays) {
19588 var n = arrays.length,
19595 while (++i < n) j += arrays[i].length;
19596 merged = new Array(j);
19602 merged[--j] = array[m];
19609 var min = function(array, f) {
19616 while (++i < n) if ((b = array[i]) != null && b >= b) { a = b; break; }
19617 while (++i < n) if ((b = array[i]) != null && a > b) a = b;
19621 while (++i < n) if ((b = f(array[i], i, array)) != null && b >= b) { a = b; break; }
19622 while (++i < n) if ((b = f(array[i], i, array)) != null && a > b) a = b;
19628 var pairs = function(array) {
19629 var i = 0, n = array.length - 1, p = array[0], pairs = new Array(n < 0 ? 0 : n);
19630 while (i < n) pairs[i] = [p, p = array[++i]];
19634 var permute = function(array, indexes) {
19635 var i = indexes.length, permutes = new Array(i);
19636 while (i--) permutes[i] = array[indexes[i]];
19640 var scan = function(array, compare) {
19641 if (!(n = array.length)) return;
19648 if (!compare) compare = ascending;
19650 while (++i < n) if (compare(xi = array[i], xj) < 0 || compare(xj, xj) !== 0) xj = xi, j = i;
19652 if (compare(xj, xj) === 0) return j;
19655 var shuffle = function(array, i0, i1) {
19656 var m = (i1 == null ? array.length : i1) - (i0 = i0 == null ? 0 : +i0),
19661 i = Math.random() * m-- | 0;
19663 array[m + i0] = array[i + i0];
19670 var sum = function(array, f) {
19677 while (++i < n) if (a = +array[i]) s += a; // Note: zero and null are equivalent.
19681 while (++i < n) if (a = +f(array[i], i, array)) s += a;
19687 var transpose = function(matrix) {
19688 if (!(n = matrix.length)) return [];
19689 for (var i = -1, m = min(matrix, length), transpose = new Array(m); ++i < m;) {
19690 for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n;) {
19691 row[j] = matrix[j][i];
19697 function length(d) {
19701 var zip = function() {
19702 return transpose(arguments);
19709 Map.prototype = map$1.prototype = {
19711 has: function(key) {
19712 return (prefix + key) in this;
19714 get: function(key) {
19715 return this[prefix + key];
19717 set: function(key, value) {
19718 this[prefix + key] = value;
19721 remove: function(key) {
19722 var property = prefix + key;
19723 return property in this && delete this[property];
19725 clear: function() {
19726 for (var property in this) if (property[0] === prefix) delete this[property];
19730 for (var property in this) if (property[0] === prefix) keys.push(property.slice(1));
19733 values: function() {
19735 for (var property in this) if (property[0] === prefix) values.push(this[property]);
19738 entries: function() {
19740 for (var property in this) if (property[0] === prefix) entries.push({key: property.slice(1), value: this[property]});
19745 for (var property in this) if (property[0] === prefix) ++size;
19748 empty: function() {
19749 for (var property in this) if (property[0] === prefix) return false;
19752 each: function(f) {
19753 for (var property in this) if (property[0] === prefix) f(this[property], property.slice(1), this);
19757 function map$1(object, f) {
19760 // Copy constructor.
19761 if (object instanceof Map) object.each(function(value, key) { map.set(key, value); });
19763 // Index array by numeric index or specified key function.
19764 else if (Array.isArray(object)) {
19769 if (f == null) while (++i < n) map.set(i, object[i]);
19770 else while (++i < n) map.set(f(o = object[i], i, object), o);
19773 // Convert object to map.
19774 else if (object) for (var key in object) map.set(key, object[key]);
19779 var nest = function() {
19786 function apply(array, depth, createResult, setResult) {
19787 if (depth >= keys.length) return rollup != null
19788 ? rollup(array) : (sortValues != null
19789 ? array.sort(sortValues)
19794 key = keys[depth++],
19797 valuesByKey = map$1(),
19799 result = createResult();
19802 if (values = valuesByKey.get(keyValue = key(value = array[i]) + "")) {
19803 values.push(value);
19805 valuesByKey.set(keyValue, [value]);
19809 valuesByKey.each(function(values, key) {
19810 setResult(result, key, apply(values, depth, createResult, setResult));
19816 function entries(map, depth) {
19817 if (++depth > keys.length) return map;
19818 var array, sortKey = sortKeys[depth - 1];
19819 if (rollup != null && depth >= keys.length) array = map.entries();
19820 else array = [], map.each(function(v, k) { array.push({key: k, values: entries(v, depth)}); });
19821 return sortKey != null ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array;
19825 object: function(array) { return apply(array, 0, createObject, setObject); },
19826 map: function(array) { return apply(array, 0, createMap, setMap); },
19827 entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); },
19828 key: function(d) { keys.push(d); return nest; },
19829 sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; },
19830 sortValues: function(order) { sortValues = order; return nest; },
19831 rollup: function(f) { rollup = f; return nest; }
19835 function createObject() {
19839 function setObject(object, key, value) {
19840 object[key] = value;
19843 function createMap() {
19847 function setMap(map, key, value) {
19848 map.set(key, value);
19853 var proto = map$1.prototype;
19855 Set.prototype = set.prototype = {
19858 add: function(value) {
19860 this[prefix + value] = value;
19863 remove: proto.remove,
19864 clear: proto.clear,
19865 values: proto.keys,
19867 empty: proto.empty,
19871 function set(object, f) {
19874 // Copy constructor.
19875 if (object instanceof Set) object.each(function(value) { set.add(value); });
19877 // Otherwise, assume it’s an array.
19879 var i = -1, n = object.length;
19880 if (f == null) while (++i < n) set.add(object[i]);
19881 else while (++i < n) set.add(f(object[i], i, object));
19887 var keys = function(map) {
19889 for (var key in map) keys.push(key);
19893 var values = function(map) {
19895 for (var key in map) values.push(map[key]);
19899 var entries = function(map) {
19901 for (var key in map) entries.push({key: key, value: map[key]});
19905 var uniform = function(min, max) {
19906 min = min == null ? 0 : +min;
19907 max = max == null ? 1 : +max;
19908 if (arguments.length === 1) max = min, min = 0;
19910 return function() {
19911 return Math.random() * max + min;
19915 var normal = function(mu, sigma) {
19917 mu = mu == null ? 0 : +mu;
19918 sigma = sigma == null ? 1 : +sigma;
19919 return function() {
19922 // If available, use the second previously-generated uniform random.
19923 if (x != null) y = x, x = null;
19925 // Otherwise, generate a new x and y.
19927 x = Math.random() * 2 - 1;
19928 y = Math.random() * 2 - 1;
19930 } while (!r || r > 1);
19932 return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r);
19936 var logNormal = function() {
19937 var randomNormal = normal.apply(this, arguments);
19938 return function() {
19939 return Math.exp(randomNormal());
19943 var irwinHall = function(n) {
19944 return function() {
19945 for (var sum = 0, i = 0; i < n; ++i) sum += Math.random();
19950 var bates = function(n) {
19951 var randomIrwinHall = irwinHall(n);
19952 return function() {
19953 return randomIrwinHall() / n;
19957 var exponential = function(lambda) {
19958 return function() {
19959 return -Math.log(1 - Math.random()) / lambda;
19963 function linear(t) {
19967 function quadIn(t) {
19971 function quadOut(t) {
19972 return t * (2 - t);
19975 function quadInOut(t) {
19976 return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2;
19979 function cubicIn(t) {
19983 function cubicOut(t) {
19984 return --t * t * t + 1;
19987 function cubicInOut(t) {
19988 return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
19993 var polyIn = (function custom(e) {
19996 function polyIn(t) {
19997 return Math.pow(t, e);
20000 polyIn.exponent = custom;
20005 var polyOut = (function custom(e) {
20008 function polyOut(t) {
20009 return 1 - Math.pow(1 - t, e);
20012 polyOut.exponent = custom;
20017 var polyInOut = (function custom(e) {
20020 function polyInOut(t) {
20021 return ((t *= 2) <= 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / 2;
20024 polyInOut.exponent = custom;
20030 var halfPi = pi / 2;
20032 function sinIn(t) {
20033 return 1 - Math.cos(t * halfPi);
20036 function sinOut(t) {
20037 return Math.sin(t * halfPi);
20040 function sinInOut(t) {
20041 return (1 - Math.cos(pi * t)) / 2;
20044 function expIn(t) {
20045 return Math.pow(2, 10 * t - 10);
20048 function expOut(t) {
20049 return 1 - Math.pow(2, -10 * t);
20052 function expInOut(t) {
20053 return ((t *= 2) <= 1 ? Math.pow(2, 10 * t - 10) : 2 - Math.pow(2, 10 - 10 * t)) / 2;
20056 function circleIn(t) {
20057 return 1 - Math.sqrt(1 - t * t);
20060 function circleOut(t) {
20061 return Math.sqrt(1 - --t * t);
20064 function circleInOut(t) {
20065 return ((t *= 2) <= 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -= 2) * t) + 1) / 2;
20077 var b0 = 1 / b1 / b1;
20079 function bounceIn(t) {
20080 return 1 - bounceOut(1 - t);
20083 function bounceOut(t) {
20084 return (t = +t) < b1 ? b0 * t * t : t < b3 ? b0 * (t -= b2) * t + b4 : t < b6 ? b0 * (t -= b5) * t + b7 : b0 * (t -= b8) * t + b9;
20087 function bounceInOut(t) {
20088 return ((t *= 2) <= 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) / 2;
20091 var overshoot = 1.70158;
20093 var backIn = (function custom(s) {
20096 function backIn(t) {
20097 return t * t * ((s + 1) * t - s);
20100 backIn.overshoot = custom;
20105 var backOut = (function custom(s) {
20108 function backOut(t) {
20109 return --t * t * ((s + 1) * t + s) + 1;
20112 backOut.overshoot = custom;
20117 var backInOut = (function custom(s) {
20120 function backInOut(t) {
20121 return ((t *= 2) < 1 ? t * t * ((s + 1) * t - s) : (t -= 2) * t * ((s + 1) * t + s) + 2) / 2;
20124 backInOut.overshoot = custom;
20129 var tau = 2 * Math.PI;
20133 var elasticIn = (function custom(a, p) {
20134 var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
20136 function elasticIn(t) {
20137 return a * Math.pow(2, 10 * --t) * Math.sin((s - t) / p);
20140 elasticIn.amplitude = function(a) { return custom(a, p * tau); };
20141 elasticIn.period = function(p) { return custom(a, p); };
20144 })(amplitude, period);
20146 var elasticOut = (function custom(a, p) {
20147 var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
20149 function elasticOut(t) {
20150 return 1 - a * Math.pow(2, -10 * (t = +t)) * Math.sin((t + s) / p);
20153 elasticOut.amplitude = function(a) { return custom(a, p * tau); };
20154 elasticOut.period = function(p) { return custom(a, p); };
20157 })(amplitude, period);
20159 var elasticInOut = (function custom(a, p) {
20160 var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
20162 function elasticInOut(t) {
20163 return ((t = t * 2 - 1) < 0
20164 ? a * Math.pow(2, 10 * t) * Math.sin((s - t) / p)
20165 : 2 - a * Math.pow(2, -10 * t) * Math.sin((s + t) / p)) / 2;
20168 elasticInOut.amplitude = function(a) { return custom(a, p * tau); };
20169 elasticInOut.period = function(p) { return custom(a, p); };
20171 return elasticInOut;
20172 })(amplitude, period);
20174 var d3polygonArea = function(polygon) {
20176 n = polygon.length,
20178 b = polygon[n - 1],
20184 area += a[1] * b[0] - a[0] * b[1];
20190 var d3polygonCentroid = function(polygon) {
20192 n = polygon.length,
20196 b = polygon[n - 1],
20203 k += c = a[0] * b[1] - b[0] * a[1];
20204 x += (a[0] + b[0]) * c;
20205 y += (a[1] + b[1]) * c;
20208 return k *= 3, [x / k, y / k];
20211 // Returns the 2D cross product of AB and AC vectors, i.e., the z-component of
20212 // the 3D cross product in a quadrant I Cartesian coordinate system (+x is
20213 // right, +y is up). Returns a positive value if ABC is counter-clockwise,
20214 // negative if clockwise, and zero if the points are collinear.
20215 var cross = function(a, b, c) {
20216 return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
20219 function lexicographicOrder(a, b) {
20220 return a[0] - b[0] || a[1] - b[1];
20223 // Computes the upper convex hull per the monotone chain algorithm.
20224 // Assumes points.length >= 3, is sorted by x, unique in y.
20225 // Returns an array of indices into points in left-to-right order.
20226 function computeUpperHullIndexes(points) {
20227 var n = points.length,
20231 for (var i = 2; i < n; ++i) {
20232 while (size > 1 && cross(points[indexes[size - 2]], points[indexes[size - 1]], points[i]) <= 0) --size;
20233 indexes[size++] = i;
20236 return indexes.slice(0, size); // remove popped points
20239 var d3polygonHull = function(points) {
20240 if ((n = points.length) < 3) return null;
20244 sortedPoints = new Array(n),
20245 flippedPoints = new Array(n);
20247 for (i = 0; i < n; ++i) sortedPoints[i] = [+points[i][0], +points[i][1], i];
20248 sortedPoints.sort(lexicographicOrder);
20249 for (i = 0; i < n; ++i) flippedPoints[i] = [sortedPoints[i][0], -sortedPoints[i][1]];
20251 var upperIndexes = computeUpperHullIndexes(sortedPoints),
20252 lowerIndexes = computeUpperHullIndexes(flippedPoints);
20254 // Construct the hull polygon, removing possible duplicate endpoints.
20255 var skipLeft = lowerIndexes[0] === upperIndexes[0],
20256 skipRight = lowerIndexes[lowerIndexes.length - 1] === upperIndexes[upperIndexes.length - 1],
20259 // Add upper hull in right-to-l order.
20260 // Then add lower hull in left-to-right order.
20261 for (i = upperIndexes.length - 1; i >= 0; --i) hull.push(points[sortedPoints[upperIndexes[i]][2]]);
20262 for (i = +skipLeft; i < lowerIndexes.length - skipRight; ++i) hull.push(points[sortedPoints[lowerIndexes[i]][2]]);
20267 var contains = function(polygon, point) {
20268 var n = polygon.length,
20269 p = polygon[n - 1],
20270 x = point[0], y = point[1],
20271 x0 = p[0], y0 = p[1],
20275 for (var i = 0; i < n; ++i) {
20276 p = polygon[i], x1 = p[0], y1 = p[1];
20277 if (((y1 > y) !== (y0 > y)) && (x < (x0 - x1) * (y - y1) / (y0 - y1) + x1)) inside = !inside;
20284 var length$1 = function(polygon) {
20286 n = polygon.length,
20287 b = polygon[n - 1],
20302 perimeter += Math.sqrt(xa * xa + ya * ya);
20308 var pi$1 = Math.PI;
20309 var tau$1 = 2 * pi$1;
20310 var epsilon = 1e-6;
20311 var tauEpsilon = tau$1 - epsilon;
20314 this._x0 = this._y0 = // start of current subpath
20315 this._x1 = this._y1 = null; // end of current subpath
20323 Path.prototype = path.prototype = {
20325 moveTo: function(x, y) {
20326 this._.push("M", this._x0 = this._x1 = +x, ",", this._y0 = this._y1 = +y);
20328 closePath: function() {
20329 if (this._x1 !== null) {
20330 this._x1 = this._x0, this._y1 = this._y0;
20334 lineTo: function(x, y) {
20335 this._.push("L", this._x1 = +x, ",", this._y1 = +y);
20337 quadraticCurveTo: function(x1, y1, x, y) {
20338 this._.push("Q", +x1, ",", +y1, ",", this._x1 = +x, ",", this._y1 = +y);
20340 bezierCurveTo: function(x1, y1, x2, y2, x, y) {
20341 this._.push("C", +x1, ",", +y1, ",", +x2, ",", +y2, ",", this._x1 = +x, ",", this._y1 = +y);
20343 arcTo: function(x1, y1, x2, y2, r) {
20344 x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;
20351 l01_2 = x01 * x01 + y01 * y01;
20353 // Is the radius negative? Error.
20354 if (r < 0) throw new Error("negative radius: " + r);
20356 // Is this path empty? Move to (x1,y1).
20357 if (this._x1 === null) {
20359 "M", this._x1 = x1, ",", this._y1 = y1
20363 // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.
20364 else if (!(l01_2 > epsilon)) {}
20366 // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?
20367 // Equivalently, is (x1,y1) coincident with (x2,y2)?
20368 // Or, is the radius zero? Line to (x1,y1).
20369 else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {
20371 "L", this._x1 = x1, ",", this._y1 = y1
20375 // Otherwise, draw an arc!
20379 l21_2 = x21 * x21 + y21 * y21,
20380 l20_2 = x20 * x20 + y20 * y20,
20381 l21 = Math.sqrt(l21_2),
20382 l01 = Math.sqrt(l01_2),
20383 l = r * Math.tan((pi$1 - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),
20387 // If the start tangent is not coincident with (x0,y0), line to.
20388 if (Math.abs(t01 - 1) > epsilon) {
20390 "L", x1 + t01 * x01, ",", y1 + t01 * y01
20395 "A", r, ",", r, ",0,0,", +(y01 * x20 > x01 * y20), ",", this._x1 = x1 + t21 * x21, ",", this._y1 = y1 + t21 * y21
20399 arc: function(x, y, r, a0, a1, ccw) {
20400 x = +x, y = +y, r = +r;
20401 var dx = r * Math.cos(a0),
20402 dy = r * Math.sin(a0),
20406 da = ccw ? a0 - a1 : a1 - a0;
20408 // Is the radius negative? Error.
20409 if (r < 0) throw new Error("negative radius: " + r);
20411 // Is this path empty? Move to (x0,y0).
20412 if (this._x1 === null) {
20418 // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).
20419 else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {
20425 // Is this arc empty? We’re done.
20428 // Is this a complete circle? Draw two arcs to complete the circle.
20429 if (da > tauEpsilon) {
20431 "A", r, ",", r, ",0,1,", cw, ",", x - dx, ",", y - dy,
20432 "A", r, ",", r, ",0,1,", cw, ",", this._x1 = x0, ",", this._y1 = y0
20436 // Otherwise, draw an arc!
20438 if (da < 0) da = da % tau$1 + tau$1;
20440 "A", r, ",", r, ",0,", +(da >= pi$1), ",", cw, ",", this._x1 = x + r * Math.cos(a1), ",", this._y1 = y + r * Math.sin(a1)
20444 rect: function(x, y, w, h) {
20445 this._.push("M", this._x0 = this._x1 = +x, ",", this._y0 = this._y1 = +y, "h", +w, "v", +h, "h", -w, "Z");
20447 toString: function() {
20448 return this._.join("");
20452 var tree_add = function(d) {
20453 var x = +this._x.call(null, d),
20454 y = +this._y.call(null, d);
20455 return add(this.cover(x, y), x, y, d);
20458 function add(tree, x, y, d) {
20459 if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points
20477 // If the tree is empty, initialize the root as a leaf.
20478 if (!node) return tree._root = leaf, tree;
20480 // Find the existing leaf for the new point, or add it.
20481 while (node.length) {
20482 if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
20483 if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
20484 if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree;
20487 // Is the new point is exactly coincident with the existing point?
20488 xp = +tree._x.call(null, node.data);
20489 yp = +tree._y.call(null, node.data);
20490 if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree;
20492 // Otherwise, split the leaf node until the old and new point are separated.
20494 parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4);
20495 if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
20496 if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
20497 } while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm)));
20498 return parent[j] = node, parent[i] = leaf, tree;
20501 function addAll(data) {
20502 var d, i, n = data.length,
20512 // Compute the points and their extent.
20513 for (i = 0; i < n; ++i) {
20514 if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue;
20517 if (x < x0) x0 = x;
20518 if (x > x1) x1 = x;
20519 if (y < y0) y0 = y;
20520 if (y > y1) y1 = y;
20523 // If there were no (valid) points, inherit the existing extent.
20524 if (x1 < x0) x0 = this._x0, x1 = this._x1;
20525 if (y1 < y0) y0 = this._y0, y1 = this._y1;
20527 // Expand the tree to cover the new points.
20528 this.cover(x0, y0).cover(x1, y1);
20530 // Add the new points.
20531 for (i = 0; i < n; ++i) {
20532 add(this, xz[i], yz[i], data[i]);
20538 var tree_cover = function(x, y) {
20539 if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points
20546 // If the quadtree has no extent, initialize them.
20547 // Integer extent are necessary so that if we later double the extent,
20548 // the existing quadrant boundaries don’t change due to floating point error!
20550 x1 = (x0 = Math.floor(x)) + 1;
20551 y1 = (y0 = Math.floor(y)) + 1;
20554 // Otherwise, double repeatedly to cover.
20555 else if (x0 > x || x > x1 || y0 > y || y > y1) {
20561 switch (i = (y < (y0 + y1) / 2) << 1 | (x < (x0 + x1) / 2)) {
20563 do parent = new Array(4), parent[i] = node, node = parent;
20564 while (z *= 2, x1 = x0 + z, y1 = y0 + z, x > x1 || y > y1);
20568 do parent = new Array(4), parent[i] = node, node = parent;
20569 while (z *= 2, x0 = x1 - z, y1 = y0 + z, x0 > x || y > y1);
20573 do parent = new Array(4), parent[i] = node, node = parent;
20574 while (z *= 2, x1 = x0 + z, y0 = y1 - z, x > x1 || y0 > y);
20578 do parent = new Array(4), parent[i] = node, node = parent;
20579 while (z *= 2, x0 = x1 - z, y0 = y1 - z, x0 > x || y0 > y);
20584 if (this._root && this._root.length) this._root = node;
20587 // If the quadtree covers the point already, just return.
20597 var tree_data = function() {
20599 this.visit(function(node) {
20600 if (!node.length) do data.push(node.data); while (node = node.next)
20605 var tree_extent = function(_) {
20606 return arguments.length
20607 ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1])
20608 : isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]];
20611 var Quad = function(node, x0, y0, x1, y1) {
20619 var tree_find = function(x, y, radius) {
20634 if (node) quads.push(new Quad(node, x0, y0, x3, y3));
20635 if (radius == null) radius = Infinity;
20637 x0 = x - radius, y0 = y - radius;
20638 x3 = x + radius, y3 = y + radius;
20642 while (q = quads.pop()) {
20644 // Stop searching if this quadrant can’t contain a closer node.
20645 if (!(node = q.node)
20646 || (x1 = q.x0) > x3
20647 || (y1 = q.y0) > y3
20648 || (x2 = q.x1) < x0
20649 || (y2 = q.y1) < y0) continue;
20651 // Bisect the current quadrant.
20653 var xm = (x1 + x2) / 2,
20654 ym = (y1 + y2) / 2;
20657 new Quad(node[3], xm, ym, x2, y2),
20658 new Quad(node[2], x1, ym, xm, y2),
20659 new Quad(node[1], xm, y1, x2, ym),
20660 new Quad(node[0], x1, y1, xm, ym)
20663 // Visit the closest quadrant first.
20664 if (i = (y >= ym) << 1 | (x >= xm)) {
20665 q = quads[quads.length - 1];
20666 quads[quads.length - 1] = quads[quads.length - 1 - i];
20667 quads[quads.length - 1 - i] = q;
20671 // Visit this point. (Visiting coincident points isn’t necessary!)
20673 var dx = x - +this._x.call(null, node.data),
20674 dy = y - +this._y.call(null, node.data),
20675 d2 = dx * dx + dy * dy;
20677 var d = Math.sqrt(radius = d2);
20678 x0 = x - d, y0 = y - d;
20679 x3 = x + d, y3 = y + d;
20688 var tree_remove = function(d) {
20689 if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points
20709 // If the tree is empty, initialize the root as a leaf.
20710 if (!node) return this;
20712 // Find the leaf node for the point.
20713 // While descending, also retain the deepest parent with a non-removed sibling.
20714 if (node.length) while (true) {
20715 if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
20716 if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
20717 if (!(parent = node, node = node[i = bottom << 1 | right])) return this;
20718 if (!node.length) break;
20719 if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i;
20722 // Find the point to remove.
20723 while (node.data !== d) if (!(previous = node, node = node.next)) return this;
20724 if (next = node.next) delete node.next;
20726 // If there are multiple coincident points, remove just the point.
20727 if (previous) return (next ? previous.next = next : delete previous.next), this;
20729 // If this is the root point, remove it.
20730 if (!parent) return this._root = next, this;
20732 // Remove this leaf.
20733 next ? parent[i] = next : delete parent[i];
20735 // If the parent now contains exactly one leaf, collapse superfluous parents.
20736 if ((node = parent[0] || parent[1] || parent[2] || parent[3])
20737 && node === (parent[3] || parent[2] || parent[1] || parent[0])
20739 if (retainer) retainer[j] = node;
20740 else this._root = node;
20746 function removeAll(data) {
20747 for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]);
20751 var tree_root = function() {
20755 var tree_size = function() {
20757 this.visit(function(node) {
20758 if (!node.length) do ++size; while (node = node.next)
20763 var tree_visit = function(callback) {
20764 var quads = [], q, node = this._root, child, x0, y0, x1, y1;
20765 if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1));
20766 while (q = quads.pop()) {
20767 if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) {
20768 var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
20769 if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
20770 if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
20771 if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
20772 if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
20778 var tree_visitAfter = function(callback) {
20779 var quads = [], next = [], q;
20780 if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1));
20781 while (q = quads.pop()) {
20784 var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
20785 if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
20786 if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
20787 if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
20788 if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
20792 while (q = next.pop()) {
20793 callback(q.node, q.x0, q.y0, q.x1, q.y1);
20798 function defaultX(d) {
20802 var tree_x = function(_) {
20803 return arguments.length ? (this._x = _, this) : this._x;
20806 function defaultY(d) {
20810 var tree_y = function(_) {
20811 return arguments.length ? (this._y = _, this) : this._y;
20814 function quadtree(nodes, x, y) {
20815 var tree = new Quadtree(x == null ? defaultX : x, y == null ? defaultY : y, NaN, NaN, NaN, NaN);
20816 return nodes == null ? tree : tree.addAll(nodes);
20819 function Quadtree(x, y, x0, y0, x1, y1) {
20826 this._root = undefined;
20829 function leaf_copy(leaf) {
20830 var copy = {data: leaf.data}, next = copy;
20831 while (leaf = leaf.next) next = next.next = {data: leaf.data};
20835 var treeProto = quadtree.prototype = Quadtree.prototype;
20837 treeProto.copy = function() {
20838 var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1),
20843 if (!node) return copy;
20845 if (!node.length) return copy._root = leaf_copy(node), copy;
20847 nodes = [{source: node, target: copy._root = new Array(4)}];
20848 while (node = nodes.pop()) {
20849 for (var i = 0; i < 4; ++i) {
20850 if (child = node.source[i]) {
20851 if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)});
20852 else node.target[i] = leaf_copy(child);
20860 treeProto.add = tree_add;
20861 treeProto.addAll = addAll;
20862 treeProto.cover = tree_cover;
20863 treeProto.data = tree_data;
20864 treeProto.extent = tree_extent;
20865 treeProto.find = tree_find;
20866 treeProto.remove = tree_remove;
20867 treeProto.removeAll = removeAll;
20868 treeProto.root = tree_root;
20869 treeProto.size = tree_size;
20870 treeProto.visit = tree_visit;
20871 treeProto.visitAfter = tree_visitAfter;
20872 treeProto.x = tree_x;
20873 treeProto.y = tree_y;
20875 var slice$1 = [].slice;
20879 function Queue(size) {
20880 if (!(size >= 1)) throw new Error;
20883 this._error = null;
20889 this._start = 0; // inside a synchronous task callback?
20892 Queue.prototype = queue.prototype = {
20893 constructor: Queue,
20894 defer: function(callback) {
20895 if (typeof callback !== "function" || this._call) throw new Error;
20896 if (this._error != null) return this;
20897 var t = slice$1.call(arguments, 1);
20899 ++this._waiting, this._tasks.push(t);
20903 abort: function() {
20904 if (this._error == null) abort(this, new Error("abort"));
20907 await: function(callback) {
20908 if (typeof callback !== "function" || this._call) throw new Error;
20909 this._call = function(error, results) { callback.apply(null, [error].concat(results)); };
20913 awaitAll: function(callback) {
20914 if (typeof callback !== "function" || this._call) throw new Error;
20915 this._call = callback;
20923 try { start(q); } // let the current task complete
20925 if (q._tasks[q._ended + q._active - 1]) abort(q, e); // task errored synchronously
20926 else if (!q._data) throw e; // await callback errored synchronously
20931 function start(q) {
20932 while (q._start = q._waiting && q._active < q._size) {
20933 var i = q._ended + q._active,
20938 --q._waiting, ++q._active;
20939 t = c.apply(null, t);
20940 if (!q._tasks[i]) continue; // task finished synchronously
20941 q._tasks[i] = t || noabort;
20945 function end(q, i) {
20946 return function(e, r) {
20947 if (!q._tasks[i]) return; // ignore multiple callbacks
20948 --q._active, ++q._ended;
20949 q._tasks[i] = null;
20950 if (q._error != null) return; // ignore secondary errors
20955 if (q._waiting) poke(q);
20956 else maybeNotify(q);
20961 function abort(q, e) {
20962 var i = q._tasks.length, t;
20963 q._error = e; // ignore active callbacks
20964 q._data = undefined; // allow gc
20965 q._waiting = NaN; // prevent starting
20968 if (t = q._tasks[i]) {
20969 q._tasks[i] = null;
20972 catch (e) { /* ignore */ }
20977 q._active = NaN; // allow notification
20981 function maybeNotify(q) {
20982 if (!q._active && q._call) {
20984 q._data = undefined; // allow gc
20985 q._call(q._error, d);
20989 function queue(concurrency) {
20990 return new Queue(arguments.length ? +concurrency : Infinity);
20993 var constant$2 = function(x) {
20994 return function constant() {
20999 var epsilon$1 = 1e-12;
21000 var pi$2 = Math.PI;
21001 var halfPi$1 = pi$2 / 2;
21002 var tau$2 = 2 * pi$2;
21004 function arcInnerRadius(d) {
21005 return d.innerRadius;
21008 function arcOuterRadius(d) {
21009 return d.outerRadius;
21012 function arcStartAngle(d) {
21013 return d.startAngle;
21016 function arcEndAngle(d) {
21020 function arcPadAngle(d) {
21021 return d && d.padAngle; // Note: optional!
21025 return x >= 1 ? halfPi$1 : x <= -1 ? -halfPi$1 : Math.asin(x);
21028 function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
21029 var x10 = x1 - x0, y10 = y1 - y0,
21030 x32 = x3 - x2, y32 = y3 - y2,
21031 t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / (y32 * x10 - x32 * y10);
21032 return [x0 + t * x10, y0 + t * y10];
21035 // Compute perpendicular offset line of length rc.
21036 // http://mathworld.wolfram.com/Circle-LineIntersection.html
21037 function cornerTangents(x0, y0, x1, y1, r1, rc, cw) {
21040 lo = (cw ? rc : -rc) / Math.sqrt(x01 * x01 + y01 * y01),
21047 x00 = (x11 + x10) / 2,
21048 y00 = (y11 + y10) / 2,
21051 d2 = dx * dx + dy * dy,
21053 D = x11 * y10 - x10 * y11,
21054 d = (dy < 0 ? -1 : 1) * Math.sqrt(Math.max(0, r * r * d2 - D * D)),
21055 cx0 = (D * dy - dx * d) / d2,
21056 cy0 = (-D * dx - dy * d) / d2,
21057 cx1 = (D * dy + dx * d) / d2,
21058 cy1 = (-D * dx + dy * d) / d2,
21064 // Pick the closer of the two intersection points.
21065 // TODO Is there a faster way to determine which intersection to use?
21066 if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;
21073 x11: cx0 * (r1 / r - 1),
21074 y11: cy0 * (r1 / r - 1)
21078 var arc = function() {
21079 var innerRadius = arcInnerRadius,
21080 outerRadius = arcOuterRadius,
21081 cornerRadius = constant$2(0),
21083 startAngle = arcStartAngle,
21084 endAngle = arcEndAngle,
21085 padAngle = arcPadAngle,
21091 r0 = +innerRadius.apply(this, arguments),
21092 r1 = +outerRadius.apply(this, arguments),
21093 a0 = startAngle.apply(this, arguments) - halfPi$1,
21094 a1 = endAngle.apply(this, arguments) - halfPi$1,
21095 da = Math.abs(a1 - a0),
21098 if (!context) context = buffer = path();
21100 // Ensure that the outer radius is always larger than the inner radius.
21101 if (r1 < r0) r = r1, r1 = r0, r0 = r;
21104 if (!(r1 > epsilon$1)) context.moveTo(0, 0);
21106 // Or is it a circle or annulus?
21107 else if (da > tau$2 - epsilon$1) {
21108 context.moveTo(r1 * Math.cos(a0), r1 * Math.sin(a0));
21109 context.arc(0, 0, r1, a0, a1, !cw);
21110 if (r0 > epsilon$1) {
21111 context.moveTo(r0 * Math.cos(a1), r0 * Math.sin(a1));
21112 context.arc(0, 0, r0, a1, a0, cw);
21116 // Or is it a circular or annular sector?
21124 ap = padAngle.apply(this, arguments) / 2,
21125 rp = (ap > epsilon$1) && (padRadius ? +padRadius.apply(this, arguments) : Math.sqrt(r0 * r0 + r1 * r1)),
21126 rc = Math.min(Math.abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),
21132 // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.
21133 if (rp > epsilon$1) {
21134 var p0 = asin(rp / r0 * Math.sin(ap)),
21135 p1 = asin(rp / r1 * Math.sin(ap));
21136 if ((da0 -= p0 * 2) > epsilon$1) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;
21137 else da0 = 0, a00 = a10 = (a0 + a1) / 2;
21138 if ((da1 -= p1 * 2) > epsilon$1) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;
21139 else da1 = 0, a01 = a11 = (a0 + a1) / 2;
21142 var x01 = r1 * Math.cos(a01),
21143 y01 = r1 * Math.sin(a01),
21144 x10 = r0 * Math.cos(a10),
21145 y10 = r0 * Math.sin(a10);
21147 // Apply rounded corners?
21148 if (rc > epsilon$1) {
21149 var x11 = r1 * Math.cos(a11),
21150 y11 = r1 * Math.sin(a11),
21151 x00 = r0 * Math.cos(a00),
21152 y00 = r0 * Math.sin(a00);
21154 // Restrict the corner radius according to the sector angle.
21156 var oc = da0 > epsilon$1 ? intersect(x01, y01, x00, y00, x11, y11, x10, y10) : [x10, y10],
21161 kc = 1 / Math.sin(Math.acos((ax * bx + ay * by) / (Math.sqrt(ax * ax + ay * ay) * Math.sqrt(bx * bx + by * by))) / 2),
21162 lc = Math.sqrt(oc[0] * oc[0] + oc[1] * oc[1]);
21163 rc0 = Math.min(rc, (r0 - lc) / (kc - 1));
21164 rc1 = Math.min(rc, (r1 - lc) / (kc + 1));
21168 // Is the sector collapsed to a line?
21169 if (!(da1 > epsilon$1)) context.moveTo(x01, y01);
21171 // Does the sector’s outer ring have rounded corners?
21172 else if (rc1 > epsilon$1) {
21173 t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);
21174 t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);
21176 context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);
21178 // Have the corners merged?
21179 if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, Math.atan2(t0.y01, t0.x01), Math.atan2(t1.y01, t1.x01), !cw);
21181 // Otherwise, draw the two corners and the ring.
21183 context.arc(t0.cx, t0.cy, rc1, Math.atan2(t0.y01, t0.x01), Math.atan2(t0.y11, t0.x11), !cw);
21184 context.arc(0, 0, r1, Math.atan2(t0.cy + t0.y11, t0.cx + t0.x11), Math.atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw);
21185 context.arc(t1.cx, t1.cy, rc1, Math.atan2(t1.y11, t1.x11), Math.atan2(t1.y01, t1.x01), !cw);
21189 // Or is the outer ring just a circular arc?
21190 else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);
21192 // Is there no inner ring, and it’s a circular sector?
21193 // Or perhaps it’s an annular sector collapsed due to padding?
21194 if (!(r0 > epsilon$1) || !(da0 > epsilon$1)) context.lineTo(x10, y10);
21196 // Does the sector’s inner ring (or point) have rounded corners?
21197 else if (rc0 > epsilon$1) {
21198 t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);
21199 t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);
21201 context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);
21203 // Have the corners merged?
21204 if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, Math.atan2(t0.y01, t0.x01), Math.atan2(t1.y01, t1.x01), !cw);
21206 // Otherwise, draw the two corners and the ring.
21208 context.arc(t0.cx, t0.cy, rc0, Math.atan2(t0.y01, t0.x01), Math.atan2(t0.y11, t0.x11), !cw);
21209 context.arc(0, 0, r0, Math.atan2(t0.cy + t0.y11, t0.cx + t0.x11), Math.atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw);
21210 context.arc(t1.cx, t1.cy, rc0, Math.atan2(t1.y11, t1.x11), Math.atan2(t1.y01, t1.x01), !cw);
21214 // Or is the inner ring just a circular arc?
21215 else context.arc(0, 0, r0, a10, a00, cw);
21218 context.closePath();
21220 if (buffer) return context = null, buffer + "" || null;
21223 arc.centroid = function() {
21224 var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,
21225 a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi$2 / 2;
21226 return [Math.cos(a) * r, Math.sin(a) * r];
21229 arc.innerRadius = function(_) {
21230 return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant$2(+_), arc) : innerRadius;
21233 arc.outerRadius = function(_) {
21234 return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant$2(+_), arc) : outerRadius;
21237 arc.cornerRadius = function(_) {
21238 return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant$2(+_), arc) : cornerRadius;
21241 arc.padRadius = function(_) {
21242 return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant$2(+_), arc) : padRadius;
21245 arc.startAngle = function(_) {
21246 return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$2(+_), arc) : startAngle;
21249 arc.endAngle = function(_) {
21250 return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$2(+_), arc) : endAngle;
21253 arc.padAngle = function(_) {
21254 return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$2(+_), arc) : padAngle;
21257 arc.context = function(_) {
21258 return arguments.length ? ((context = _ == null ? null : _), arc) : context;
21264 function Linear(context) {
21265 this._context = context;
21268 Linear.prototype = {
21269 areaStart: function() {
21272 areaEnd: function() {
21275 lineStart: function() {
21278 lineEnd: function() {
21279 if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
21280 this._line = 1 - this._line;
21282 point: function(x, y) {
21284 switch (this._point) {
21285 case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
21286 case 1: this._point = 2; // proceed
21287 default: this._context.lineTo(x, y); break;
21292 var curveLinear = function(context) {
21293 return new Linear(context);
21304 var line = function() {
21307 defined = constant$2(true),
21309 curve = curveLinear,
21312 function line(data) {
21319 if (context == null) output = curve(buffer = path());
21321 for (i = 0; i <= n; ++i) {
21322 if (!(i < n && defined(d = data[i], i, data)) === defined0) {
21323 if (defined0 = !defined0) output.lineStart();
21324 else output.lineEnd();
21326 if (defined0) output.point(+x$$1(d, i, data), +y$$1(d, i, data));
21329 if (buffer) return output = null, buffer + "" || null;
21332 line.x = function(_) {
21333 return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$2(+_), line) : x$$1;
21336 line.y = function(_) {
21337 return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$2(+_), line) : y$$1;
21340 line.defined = function(_) {
21341 return arguments.length ? (defined = typeof _ === "function" ? _ : constant$2(!!_), line) : defined;
21344 line.curve = function(_) {
21345 return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;
21348 line.context = function(_) {
21349 return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;
21355 var area = function() {
21358 y0 = constant$2(0),
21360 defined = constant$2(true),
21362 curve = curveLinear,
21365 function area(data) {
21373 x0z = new Array(n),
21374 y0z = new Array(n);
21376 if (context == null) output = curve(buffer = path());
21378 for (i = 0; i <= n; ++i) {
21379 if (!(i < n && defined(d = data[i], i, data)) === defined0) {
21380 if (defined0 = !defined0) {
21382 output.areaStart();
21383 output.lineStart();
21386 output.lineStart();
21387 for (k = i - 1; k >= j; --k) {
21388 output.point(x0z[k], y0z[k]);
21395 x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);
21396 output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);
21400 if (buffer) return output = null, buffer + "" || null;
21403 function arealine() {
21404 return line().defined(defined).curve(curve).context(context);
21407 area.x = function(_) {
21408 return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$2(+_), x1 = null, area) : x0;
21411 area.x0 = function(_) {
21412 return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$2(+_), area) : x0;
21415 area.x1 = function(_) {
21416 return arguments.length ? (x1 = _ == null ? null : typeof _ === "function" ? _ : constant$2(+_), area) : x1;
21419 area.y = function(_) {
21420 return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$2(+_), y1 = null, area) : y0;
21423 area.y0 = function(_) {
21424 return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$2(+_), area) : y0;
21427 area.y1 = function(_) {
21428 return arguments.length ? (y1 = _ == null ? null : typeof _ === "function" ? _ : constant$2(+_), area) : y1;
21432 area.lineY0 = function() {
21433 return arealine().x(x0).y(y0);
21436 area.lineY1 = function() {
21437 return arealine().x(x0).y(y1);
21440 area.lineX1 = function() {
21441 return arealine().x(x1).y(y0);
21444 area.defined = function(_) {
21445 return arguments.length ? (defined = typeof _ === "function" ? _ : constant$2(!!_), area) : defined;
21448 area.curve = function(_) {
21449 return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;
21452 area.context = function(_) {
21453 return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;
21459 var descending$1 = function(a, b) {
21460 return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
21463 var identity$1 = function(d) {
21467 var pie = function() {
21468 var value = identity$1,
21469 sortValues = descending$1,
21471 startAngle = constant$2(0),
21472 endAngle = constant$2(tau$2),
21473 padAngle = constant$2(0);
21475 function pie(data) {
21481 index = new Array(n),
21482 arcs = new Array(n),
21483 a0 = +startAngle.apply(this, arguments),
21484 da = Math.min(tau$2, Math.max(-tau$2, endAngle.apply(this, arguments) - a0)),
21486 p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)),
21487 pa = p * (da < 0 ? -1 : 1),
21490 for (i = 0; i < n; ++i) {
21491 if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) {
21496 // Optionally sort the arcs by previously-computed values or by data.
21497 if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); });
21498 else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); });
21500 // Compute the arcs! They are stored in the original data's order.
21501 for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) {
21502 j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = {
21515 pie.value = function(_) {
21516 return arguments.length ? (value = typeof _ === "function" ? _ : constant$2(+_), pie) : value;
21519 pie.sortValues = function(_) {
21520 return arguments.length ? (sortValues = _, sort = null, pie) : sortValues;
21523 pie.sort = function(_) {
21524 return arguments.length ? (sort = _, sortValues = null, pie) : sort;
21527 pie.startAngle = function(_) {
21528 return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$2(+_), pie) : startAngle;
21531 pie.endAngle = function(_) {
21532 return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$2(+_), pie) : endAngle;
21535 pie.padAngle = function(_) {
21536 return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$2(+_), pie) : padAngle;
21542 var curveRadialLinear = curveRadial(curveLinear);
21544 function Radial(curve) {
21545 this._curve = curve;
21548 Radial.prototype = {
21549 areaStart: function() {
21550 this._curve.areaStart();
21552 areaEnd: function() {
21553 this._curve.areaEnd();
21555 lineStart: function() {
21556 this._curve.lineStart();
21558 lineEnd: function() {
21559 this._curve.lineEnd();
21561 point: function(a, r) {
21562 this._curve.point(r * Math.sin(a), r * -Math.cos(a));
21566 function curveRadial(curve) {
21568 function radial(context) {
21569 return new Radial(curve(context));
21572 radial._curve = curve;
21577 function radialLine(l) {
21580 l.angle = l.x, delete l.x;
21581 l.radius = l.y, delete l.y;
21583 l.curve = function(_) {
21584 return arguments.length ? c(curveRadial(_)) : c()._curve;
21590 var radialLine$1 = function() {
21591 return radialLine(line().curve(curveRadialLinear));
21594 var radialArea = function() {
21595 var a = area().curve(curveRadialLinear),
21602 a.angle = a.x, delete a.x;
21603 a.startAngle = a.x0, delete a.x0;
21604 a.endAngle = a.x1, delete a.x1;
21605 a.radius = a.y, delete a.y;
21606 a.innerRadius = a.y0, delete a.y0;
21607 a.outerRadius = a.y1, delete a.y1;
21608 a.lineStartAngle = function() { return radialLine(x0()); }, delete a.lineX0;
21609 a.lineEndAngle = function() { return radialLine(x1()); }, delete a.lineX1;
21610 a.lineInnerRadius = function() { return radialLine(y0()); }, delete a.lineY0;
21611 a.lineOuterRadius = function() { return radialLine(y1()); }, delete a.lineY1;
21613 a.curve = function(_) {
21614 return arguments.length ? c(curveRadial(_)) : c()._curve;
21621 draw: function(context, size) {
21622 var r = Math.sqrt(size / pi$2);
21623 context.moveTo(r, 0);
21624 context.arc(0, 0, r, 0, tau$2);
21629 draw: function(context, size) {
21630 var r = Math.sqrt(size / 5) / 2;
21631 context.moveTo(-3 * r, -r);
21632 context.lineTo(-r, -r);
21633 context.lineTo(-r, -3 * r);
21634 context.lineTo(r, -3 * r);
21635 context.lineTo(r, -r);
21636 context.lineTo(3 * r, -r);
21637 context.lineTo(3 * r, r);
21638 context.lineTo(r, r);
21639 context.lineTo(r, 3 * r);
21640 context.lineTo(-r, 3 * r);
21641 context.lineTo(-r, r);
21642 context.lineTo(-3 * r, r);
21643 context.closePath();
21647 var tan30 = Math.sqrt(1 / 3);
21648 var tan30_2 = tan30 * 2;
21651 draw: function(context, size) {
21652 var y = Math.sqrt(size / tan30_2),
21654 context.moveTo(0, -y);
21655 context.lineTo(x, 0);
21656 context.lineTo(0, y);
21657 context.lineTo(-x, 0);
21658 context.closePath();
21662 var ka = 0.89081309152928522810;
21663 var kr = Math.sin(pi$2 / 10) / Math.sin(7 * pi$2 / 10);
21664 var kx = Math.sin(tau$2 / 10) * kr;
21665 var ky = -Math.cos(tau$2 / 10) * kr;
21668 draw: function(context, size) {
21669 var r = Math.sqrt(size * ka),
21672 context.moveTo(0, -r);
21673 context.lineTo(x, y);
21674 for (var i = 1; i < 5; ++i) {
21675 var a = tau$2 * i / 5,
21678 context.lineTo(s * r, -c * r);
21679 context.lineTo(c * x - s * y, s * x + c * y);
21681 context.closePath();
21686 draw: function(context, size) {
21687 var w = Math.sqrt(size),
21689 context.rect(x, x, w, w);
21693 var sqrt3 = Math.sqrt(3);
21696 draw: function(context, size) {
21697 var y = -Math.sqrt(size / (sqrt3 * 3));
21698 context.moveTo(0, y * 2);
21699 context.lineTo(-sqrt3 * y, -y);
21700 context.lineTo(sqrt3 * y, -y);
21701 context.closePath();
21706 var s = Math.sqrt(3) / 2;
21707 var k = 1 / Math.sqrt(12);
21708 var a = (k / 2 + 1) * 3;
21711 draw: function(context, size) {
21712 var r = Math.sqrt(size / a),
21719 context.moveTo(x0, y0);
21720 context.lineTo(x1, y1);
21721 context.lineTo(x2, y2);
21722 context.lineTo(c * x0 - s * y0, s * x0 + c * y0);
21723 context.lineTo(c * x1 - s * y1, s * x1 + c * y1);
21724 context.lineTo(c * x2 - s * y2, s * x2 + c * y2);
21725 context.lineTo(c * x0 + s * y0, c * y0 - s * x0);
21726 context.lineTo(c * x1 + s * y1, c * y1 - s * x1);
21727 context.lineTo(c * x2 + s * y2, c * y2 - s * x2);
21728 context.closePath();
21742 var symbol = function() {
21743 var type = constant$2(circle),
21744 size = constant$2(64),
21747 function symbol() {
21749 if (!context) context = buffer = path();
21750 type.apply(this, arguments).draw(context, +size.apply(this, arguments));
21751 if (buffer) return context = null, buffer + "" || null;
21754 symbol.type = function(_) {
21755 return arguments.length ? (type = typeof _ === "function" ? _ : constant$2(_), symbol) : type;
21758 symbol.size = function(_) {
21759 return arguments.length ? (size = typeof _ === "function" ? _ : constant$2(+_), symbol) : size;
21762 symbol.context = function(_) {
21763 return arguments.length ? (context = _ == null ? null : _, symbol) : context;
21769 var noop = function() {};
21771 function point(that, x, y) {
21772 that._context.bezierCurveTo(
21773 (2 * that._x0 + that._x1) / 3,
21774 (2 * that._y0 + that._y1) / 3,
21775 (that._x0 + 2 * that._x1) / 3,
21776 (that._y0 + 2 * that._y1) / 3,
21777 (that._x0 + 4 * that._x1 + x) / 6,
21778 (that._y0 + 4 * that._y1 + y) / 6
21782 function Basis(context) {
21783 this._context = context;
21786 Basis.prototype = {
21787 areaStart: function() {
21790 areaEnd: function() {
21793 lineStart: function() {
21794 this._x0 = this._x1 =
21795 this._y0 = this._y1 = NaN;
21798 lineEnd: function() {
21799 switch (this._point) {
21800 case 3: point(this, this._x1, this._y1); // proceed
21801 case 2: this._context.lineTo(this._x1, this._y1); break;
21803 if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
21804 this._line = 1 - this._line;
21806 point: function(x, y) {
21808 switch (this._point) {
21809 case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
21810 case 1: this._point = 2; break;
21811 case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed
21812 default: point(this, x, y); break;
21814 this._x0 = this._x1, this._x1 = x;
21815 this._y0 = this._y1, this._y1 = y;
21819 var basis = function(context) {
21820 return new Basis(context);
21823 function BasisClosed(context) {
21824 this._context = context;
21827 BasisClosed.prototype = {
21830 lineStart: function() {
21831 this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =
21832 this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;
21835 lineEnd: function() {
21836 switch (this._point) {
21838 this._context.moveTo(this._x2, this._y2);
21839 this._context.closePath();
21843 this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);
21844 this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);
21845 this._context.closePath();
21849 this.point(this._x2, this._y2);
21850 this.point(this._x3, this._y3);
21851 this.point(this._x4, this._y4);
21856 point: function(x, y) {
21858 switch (this._point) {
21859 case 0: this._point = 1; this._x2 = x, this._y2 = y; break;
21860 case 1: this._point = 2; this._x3 = x, this._y3 = y; break;
21861 case 2: this._point = 3; this._x4 = x, this._y4 = y; this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6); break;
21862 default: point(this, x, y); break;
21864 this._x0 = this._x1, this._x1 = x;
21865 this._y0 = this._y1, this._y1 = y;
21869 var basisClosed = function(context) {
21870 return new BasisClosed(context);
21873 function BasisOpen(context) {
21874 this._context = context;
21877 BasisOpen.prototype = {
21878 areaStart: function() {
21881 areaEnd: function() {
21884 lineStart: function() {
21885 this._x0 = this._x1 =
21886 this._y0 = this._y1 = NaN;
21889 lineEnd: function() {
21890 if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
21891 this._line = 1 - this._line;
21893 point: function(x, y) {
21895 switch (this._point) {
21896 case 0: this._point = 1; break;
21897 case 1: this._point = 2; break;
21898 case 2: this._point = 3; var x0 = (this._x0 + 4 * this._x1 + x) / 6, y0 = (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break;
21899 case 3: this._point = 4; // proceed
21900 default: point(this, x, y); break;
21902 this._x0 = this._x1, this._x1 = x;
21903 this._y0 = this._y1, this._y1 = y;
21907 var basisOpen = function(context) {
21908 return new BasisOpen(context);
21911 function Bundle(context, beta) {
21912 this._basis = new Basis(context);
21916 Bundle.prototype = {
21917 lineStart: function() {
21920 this._basis.lineStart();
21922 lineEnd: function() {
21938 this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),
21939 this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)
21944 this._x = this._y = null;
21945 this._basis.lineEnd();
21947 point: function(x, y) {
21953 var bundle = (function custom(beta) {
21955 function bundle(context) {
21956 return beta === 1 ? new Basis(context) : new Bundle(context, beta);
21959 bundle.beta = function(beta) {
21960 return custom(+beta);
21966 function point$1(that, x, y) {
21967 that._context.bezierCurveTo(
21968 that._x1 + that._k * (that._x2 - that._x0),
21969 that._y1 + that._k * (that._y2 - that._y0),
21970 that._x2 + that._k * (that._x1 - x),
21971 that._y2 + that._k * (that._y1 - y),
21977 function Cardinal(context, tension) {
21978 this._context = context;
21979 this._k = (1 - tension) / 6;
21982 Cardinal.prototype = {
21983 areaStart: function() {
21986 areaEnd: function() {
21989 lineStart: function() {
21990 this._x0 = this._x1 = this._x2 =
21991 this._y0 = this._y1 = this._y2 = NaN;
21994 lineEnd: function() {
21995 switch (this._point) {
21996 case 2: this._context.lineTo(this._x2, this._y2); break;
21997 case 3: point$1(this, this._x1, this._y1); break;
21999 if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
22000 this._line = 1 - this._line;
22002 point: function(x, y) {
22004 switch (this._point) {
22005 case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
22006 case 1: this._point = 2; this._x1 = x, this._y1 = y; break;
22007 case 2: this._point = 3; // proceed
22008 default: point$1(this, x, y); break;
22010 this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
22011 this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
22015 var cardinal = (function custom(tension) {
22017 function cardinal(context) {
22018 return new Cardinal(context, tension);
22021 cardinal.tension = function(tension) {
22022 return custom(+tension);
22028 function CardinalClosed(context, tension) {
22029 this._context = context;
22030 this._k = (1 - tension) / 6;
22033 CardinalClosed.prototype = {
22036 lineStart: function() {
22037 this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
22038 this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
22041 lineEnd: function() {
22042 switch (this._point) {
22044 this._context.moveTo(this._x3, this._y3);
22045 this._context.closePath();
22049 this._context.lineTo(this._x3, this._y3);
22050 this._context.closePath();
22054 this.point(this._x3, this._y3);
22055 this.point(this._x4, this._y4);
22056 this.point(this._x5, this._y5);
22061 point: function(x, y) {
22063 switch (this._point) {
22064 case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
22065 case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
22066 case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
22067 default: point$1(this, x, y); break;
22069 this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
22070 this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
22074 var cardinalClosed = (function custom(tension) {
22076 function cardinal(context) {
22077 return new CardinalClosed(context, tension);
22080 cardinal.tension = function(tension) {
22081 return custom(+tension);
22087 function CardinalOpen(context, tension) {
22088 this._context = context;
22089 this._k = (1 - tension) / 6;
22092 CardinalOpen.prototype = {
22093 areaStart: function() {
22096 areaEnd: function() {
22099 lineStart: function() {
22100 this._x0 = this._x1 = this._x2 =
22101 this._y0 = this._y1 = this._y2 = NaN;
22104 lineEnd: function() {
22105 if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
22106 this._line = 1 - this._line;
22108 point: function(x, y) {
22110 switch (this._point) {
22111 case 0: this._point = 1; break;
22112 case 1: this._point = 2; break;
22113 case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
22114 case 3: this._point = 4; // proceed
22115 default: point$1(this, x, y); break;
22117 this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
22118 this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
22122 var cardinalOpen = (function custom(tension) {
22124 function cardinal(context) {
22125 return new CardinalOpen(context, tension);
22128 cardinal.tension = function(tension) {
22129 return custom(+tension);
22135 function point$2(that, x, y) {
22141 if (that._l01_a > epsilon$1) {
22142 var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a,
22143 n = 3 * that._l01_a * (that._l01_a + that._l12_a);
22144 x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;
22145 y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;
22148 if (that._l23_a > epsilon$1) {
22149 var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a,
22150 m = 3 * that._l23_a * (that._l23_a + that._l12_a);
22151 x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;
22152 y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;
22155 that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);
22158 function CatmullRom(context, alpha) {
22159 this._context = context;
22160 this._alpha = alpha;
22163 CatmullRom.prototype = {
22164 areaStart: function() {
22167 areaEnd: function() {
22170 lineStart: function() {
22171 this._x0 = this._x1 = this._x2 =
22172 this._y0 = this._y1 = this._y2 = NaN;
22173 this._l01_a = this._l12_a = this._l23_a =
22174 this._l01_2a = this._l12_2a = this._l23_2a =
22177 lineEnd: function() {
22178 switch (this._point) {
22179 case 2: this._context.lineTo(this._x2, this._y2); break;
22180 case 3: this.point(this._x2, this._y2); break;
22182 if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
22183 this._line = 1 - this._line;
22185 point: function(x, y) {
22189 var x23 = this._x2 - x,
22190 y23 = this._y2 - y;
22191 this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
22194 switch (this._point) {
22195 case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
22196 case 1: this._point = 2; break;
22197 case 2: this._point = 3; // proceed
22198 default: point$2(this, x, y); break;
22201 this._l01_a = this._l12_a, this._l12_a = this._l23_a;
22202 this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
22203 this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
22204 this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
22208 var catmullRom = (function custom(alpha) {
22210 function catmullRom(context) {
22211 return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0);
22214 catmullRom.alpha = function(alpha) {
22215 return custom(+alpha);
22221 function CatmullRomClosed(context, alpha) {
22222 this._context = context;
22223 this._alpha = alpha;
22226 CatmullRomClosed.prototype = {
22229 lineStart: function() {
22230 this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
22231 this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
22232 this._l01_a = this._l12_a = this._l23_a =
22233 this._l01_2a = this._l12_2a = this._l23_2a =
22236 lineEnd: function() {
22237 switch (this._point) {
22239 this._context.moveTo(this._x3, this._y3);
22240 this._context.closePath();
22244 this._context.lineTo(this._x3, this._y3);
22245 this._context.closePath();
22249 this.point(this._x3, this._y3);
22250 this.point(this._x4, this._y4);
22251 this.point(this._x5, this._y5);
22256 point: function(x, y) {
22260 var x23 = this._x2 - x,
22261 y23 = this._y2 - y;
22262 this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
22265 switch (this._point) {
22266 case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
22267 case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
22268 case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
22269 default: point$2(this, x, y); break;
22272 this._l01_a = this._l12_a, this._l12_a = this._l23_a;
22273 this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
22274 this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
22275 this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
22279 var catmullRomClosed = (function custom(alpha) {
22281 function catmullRom(context) {
22282 return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0);
22285 catmullRom.alpha = function(alpha) {
22286 return custom(+alpha);
22292 function CatmullRomOpen(context, alpha) {
22293 this._context = context;
22294 this._alpha = alpha;
22297 CatmullRomOpen.prototype = {
22298 areaStart: function() {
22301 areaEnd: function() {
22304 lineStart: function() {
22305 this._x0 = this._x1 = this._x2 =
22306 this._y0 = this._y1 = this._y2 = NaN;
22307 this._l01_a = this._l12_a = this._l23_a =
22308 this._l01_2a = this._l12_2a = this._l23_2a =
22311 lineEnd: function() {
22312 if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
22313 this._line = 1 - this._line;
22315 point: function(x, y) {
22319 var x23 = this._x2 - x,
22320 y23 = this._y2 - y;
22321 this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
22324 switch (this._point) {
22325 case 0: this._point = 1; break;
22326 case 1: this._point = 2; break;
22327 case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
22328 case 3: this._point = 4; // proceed
22329 default: point$2(this, x, y); break;
22332 this._l01_a = this._l12_a, this._l12_a = this._l23_a;
22333 this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
22334 this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
22335 this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
22339 var catmullRomOpen = (function custom(alpha) {
22341 function catmullRom(context) {
22342 return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0);
22345 catmullRom.alpha = function(alpha) {
22346 return custom(+alpha);
22352 function LinearClosed(context) {
22353 this._context = context;
22356 LinearClosed.prototype = {
22359 lineStart: function() {
22362 lineEnd: function() {
22363 if (this._point) this._context.closePath();
22365 point: function(x, y) {
22367 if (this._point) this._context.lineTo(x, y);
22368 else this._point = 1, this._context.moveTo(x, y);
22372 var linearClosed = function(context) {
22373 return new LinearClosed(context);
22377 return x < 0 ? -1 : 1;
22380 // Calculate the slopes of the tangents (Hermite-type interpolation) based on
22381 // the following paper: Steffen, M. 1990. A Simple Method for Monotonic
22382 // Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.
22383 // NOV(II), P. 443, 1990.
22384 function slope3(that, x2, y2) {
22385 var h0 = that._x1 - that._x0,
22386 h1 = x2 - that._x1,
22387 s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),
22388 s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),
22389 p = (s0 * h1 + s1 * h0) / (h0 + h1);
22390 return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;
22393 // Calculate a one-sided slope.
22394 function slope2(that, t) {
22395 var h = that._x1 - that._x0;
22396 return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;
22399 // According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations
22400 // "you can express cubic Hermite interpolation in terms of cubic Bézier curves
22401 // with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1".
22402 function point$3(that, t0, t1) {
22407 dx = (x1 - x0) / 3;
22408 that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);
22411 function MonotoneX(context) {
22412 this._context = context;
22415 MonotoneX.prototype = {
22416 areaStart: function() {
22419 areaEnd: function() {
22422 lineStart: function() {
22423 this._x0 = this._x1 =
22424 this._y0 = this._y1 =
22428 lineEnd: function() {
22429 switch (this._point) {
22430 case 2: this._context.lineTo(this._x1, this._y1); break;
22431 case 3: point$3(this, this._t0, slope2(this, this._t0)); break;
22433 if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
22434 this._line = 1 - this._line;
22436 point: function(x, y) {
22440 if (x === this._x1 && y === this._y1) return; // Ignore coincident points.
22441 switch (this._point) {
22442 case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
22443 case 1: this._point = 2; break;
22444 case 2: this._point = 3; point$3(this, slope2(this, t1 = slope3(this, x, y)), t1); break;
22445 default: point$3(this, this._t0, t1 = slope3(this, x, y)); break;
22448 this._x0 = this._x1, this._x1 = x;
22449 this._y0 = this._y1, this._y1 = y;
22454 function MonotoneY(context) {
22455 this._context = new ReflectContext(context);
22458 (MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {
22459 MonotoneX.prototype.point.call(this, y, x);
22462 function ReflectContext(context) {
22463 this._context = context;
22466 ReflectContext.prototype = {
22467 moveTo: function(x, y) { this._context.moveTo(y, x); },
22468 closePath: function() { this._context.closePath(); },
22469 lineTo: function(x, y) { this._context.lineTo(y, x); },
22470 bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }
22473 function monotoneX(context) {
22474 return new MonotoneX(context);
22477 function monotoneY(context) {
22478 return new MonotoneY(context);
22481 function Natural(context) {
22482 this._context = context;
22485 Natural.prototype = {
22486 areaStart: function() {
22489 areaEnd: function() {
22492 lineStart: function() {
22496 lineEnd: function() {
22502 this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);
22504 this._context.lineTo(x[1], y[1]);
22506 var px = controlPoints(x),
22507 py = controlPoints(y);
22508 for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {
22509 this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);
22514 if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();
22515 this._line = 1 - this._line;
22516 this._x = this._y = null;
22518 point: function(x, y) {
22524 // See https://www.particleincell.com/2012/bezier-splines/ for derivation.
22525 function controlPoints(x) {
22532 a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];
22533 for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];
22534 a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];
22535 for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];
22536 a[n - 1] = r[n - 1] / b[n - 1];
22537 for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];
22538 b[n - 1] = (x[n] + a[n - 1]) / 2;
22539 for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];
22543 var natural = function(context) {
22544 return new Natural(context);
22547 function Step(context, t) {
22548 this._context = context;
22553 areaStart: function() {
22556 areaEnd: function() {
22559 lineStart: function() {
22560 this._x = this._y = NaN;
22563 lineEnd: function() {
22564 if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);
22565 if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
22566 if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;
22568 point: function(x, y) {
22570 switch (this._point) {
22571 case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
22572 case 1: this._point = 2; // proceed
22574 if (this._t <= 0) {
22575 this._context.lineTo(this._x, y);
22576 this._context.lineTo(x, y);
22578 var x1 = this._x * (1 - this._t) + x * this._t;
22579 this._context.lineTo(x1, this._y);
22580 this._context.lineTo(x1, y);
22585 this._x = x, this._y = y;
22589 var step = function(context) {
22590 return new Step(context, 0.5);
22593 function stepBefore(context) {
22594 return new Step(context, 0);
22597 function stepAfter(context) {
22598 return new Step(context, 1);
22601 var slice$2 = Array.prototype.slice;
22603 var none = function(series, order) {
22604 if (!((n = series.length) > 1)) return;
22605 for (var i = 1, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) {
22606 s0 = s1, s1 = series[order[i]];
22607 for (var j = 0; j < m; ++j) {
22608 s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1];
22613 var none$1 = function(series) {
22614 var n = series.length, o = new Array(n);
22615 while (--n >= 0) o[n] = n;
22619 function stackValue(d, key) {
22623 var stack = function() {
22624 var keys = constant$2([]),
22627 value = stackValue;
22629 function stack(data) {
22630 var kz = keys.apply(this, arguments),
22637 for (i = 0; i < n; ++i) {
22638 for (var ki = kz[i], si = sz[i] = new Array(m), j = 0, sij; j < m; ++j) {
22639 si[j] = sij = [0, +value(data[j], ki, j, data)];
22640 sij.data = data[j];
22645 for (i = 0, oz = order(sz); i < n; ++i) {
22646 sz[oz[i]].index = i;
22653 stack.keys = function(_) {
22654 return arguments.length ? (keys = typeof _ === "function" ? _ : constant$2(slice$2.call(_)), stack) : keys;
22657 stack.value = function(_) {
22658 return arguments.length ? (value = typeof _ === "function" ? _ : constant$2(+_), stack) : value;
22661 stack.order = function(_) {
22662 return arguments.length ? (order = _ == null ? none$1 : typeof _ === "function" ? _ : constant$2(slice$2.call(_)), stack) : order;
22665 stack.offset = function(_) {
22666 return arguments.length ? (offset = _ == null ? none : _, stack) : offset;
22672 var expand = function(series, order) {
22673 if (!((n = series.length) > 0)) return;
22674 for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) {
22675 for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0;
22676 if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y;
22678 none(series, order);
22681 var silhouette = function(series, order) {
22682 if (!((n = series.length) > 0)) return;
22683 for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) {
22684 for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0;
22685 s0[j][1] += s0[j][0] = -y / 2;
22687 none(series, order);
22690 var wiggle = function(series, order) {
22691 if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return;
22692 for (var y = 0, j = 1, s0, m, n; j < m; ++j) {
22693 for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) {
22694 var si = series[order[i]],
22695 sij0 = si[j][1] || 0,
22696 sij1 = si[j - 1][1] || 0,
22697 s3 = (sij0 - sij1) / 2;
22698 for (var k = 0; k < i; ++k) {
22699 var sk = series[order[k]],
22700 skj0 = sk[j][1] || 0,
22701 skj1 = sk[j - 1][1] || 0;
22704 s1 += sij0, s2 += s3 * sij0;
22706 s0[j - 1][1] += s0[j - 1][0] = y;
22707 if (s1) y -= s2 / s1;
22709 s0[j - 1][1] += s0[j - 1][0] = y;
22710 none(series, order);
22713 var ascending$1 = function(series) {
22714 var sums = series.map(sum$1);
22715 return none$1(series).sort(function(a, b) { return sums[a] - sums[b]; });
22718 function sum$1(series) {
22719 var s = 0, i = -1, n = series.length, v;
22720 while (++i < n) if (v = +series[i][1]) s += v;
22724 var descending$2 = function(series) {
22725 return ascending$1(series).reverse();
22728 var insideOut = function(series) {
22729 var n = series.length,
22732 sums = series.map(sum$1),
22733 order = none$1(series).sort(function(a, b) { return sums[b] - sums[a]; }),
22739 for (i = 0; i < n; ++i) {
22741 if (top < bottom) {
22750 return bottoms.reverse().concat(tops);
22753 var reverse = function(series) {
22754 return none$1(series).reverse();
22757 var define$1 = function(constructor, factory, prototype) {
22758 constructor.prototype = factory.prototype = prototype;
22759 prototype.constructor = constructor;
22762 function extend(parent, definition) {
22763 var prototype = Object.create(parent.prototype);
22764 for (var key in definition) prototype[key] = definition[key];
22768 function Color() {}
22771 var brighter = 1 / darker;
22773 var reHex3 = /^#([0-9a-f]{3})$/;
22774 var reHex6 = /^#([0-9a-f]{6})$/;
22775 var reRgbInteger = /^rgb\(\s*([-+]?\d+)\s*,\s*([-+]?\d+)\s*,\s*([-+]?\d+)\s*\)$/;
22776 var reRgbPercent = /^rgb\(\s*([-+]?\d+(?:\.\d+)?)%\s*,\s*([-+]?\d+(?:\.\d+)?)%\s*,\s*([-+]?\d+(?:\.\d+)?)%\s*\)$/;
22777 var reRgbaInteger = /^rgba\(\s*([-+]?\d+)\s*,\s*([-+]?\d+)\s*,\s*([-+]?\d+)\s*,\s*([-+]?\d+(?:\.\d+)?)\s*\)$/;
22778 var reRgbaPercent = /^rgba\(\s*([-+]?\d+(?:\.\d+)?)%\s*,\s*([-+]?\d+(?:\.\d+)?)%\s*,\s*([-+]?\d+(?:\.\d+)?)%\s*,\s*([-+]?\d+(?:\.\d+)?)\s*\)$/;
22779 var reHslPercent = /^hsl\(\s*([-+]?\d+(?:\.\d+)?)\s*,\s*([-+]?\d+(?:\.\d+)?)%\s*,\s*([-+]?\d+(?:\.\d+)?)%\s*\)$/;
22780 var reHslaPercent = /^hsla\(\s*([-+]?\d+(?:\.\d+)?)\s*,\s*([-+]?\d+(?:\.\d+)?)%\s*,\s*([-+]?\d+(?:\.\d+)?)%\s*,\s*([-+]?\d+(?:\.\d+)?)\s*\)$/;
22783 aliceblue: 0xf0f8ff,
22784 antiquewhite: 0xfaebd7,
22786 aquamarine: 0x7fffd4,
22791 blanchedalmond: 0xffebcd,
22793 blueviolet: 0x8a2be2,
22795 burlywood: 0xdeb887,
22796 cadetblue: 0x5f9ea0,
22797 chartreuse: 0x7fff00,
22798 chocolate: 0xd2691e,
22800 cornflowerblue: 0x6495ed,
22801 cornsilk: 0xfff8dc,
22804 darkblue: 0x00008b,
22805 darkcyan: 0x008b8b,
22806 darkgoldenrod: 0xb8860b,
22807 darkgray: 0xa9a9a9,
22808 darkgreen: 0x006400,
22809 darkgrey: 0xa9a9a9,
22810 darkkhaki: 0xbdb76b,
22811 darkmagenta: 0x8b008b,
22812 darkolivegreen: 0x556b2f,
22813 darkorange: 0xff8c00,
22814 darkorchid: 0x9932cc,
22816 darksalmon: 0xe9967a,
22817 darkseagreen: 0x8fbc8f,
22818 darkslateblue: 0x483d8b,
22819 darkslategray: 0x2f4f4f,
22820 darkslategrey: 0x2f4f4f,
22821 darkturquoise: 0x00ced1,
22822 darkviolet: 0x9400d3,
22823 deeppink: 0xff1493,
22824 deepskyblue: 0x00bfff,
22827 dodgerblue: 0x1e90ff,
22828 firebrick: 0xb22222,
22829 floralwhite: 0xfffaf0,
22830 forestgreen: 0x228b22,
22832 gainsboro: 0xdcdcdc,
22833 ghostwhite: 0xf8f8ff,
22835 goldenrod: 0xdaa520,
22838 greenyellow: 0xadff2f,
22840 honeydew: 0xf0fff0,
22842 indianred: 0xcd5c5c,
22846 lavender: 0xe6e6fa,
22847 lavenderblush: 0xfff0f5,
22848 lawngreen: 0x7cfc00,
22849 lemonchiffon: 0xfffacd,
22850 lightblue: 0xadd8e6,
22851 lightcoral: 0xf08080,
22852 lightcyan: 0xe0ffff,
22853 lightgoldenrodyellow: 0xfafad2,
22854 lightgray: 0xd3d3d3,
22855 lightgreen: 0x90ee90,
22856 lightgrey: 0xd3d3d3,
22857 lightpink: 0xffb6c1,
22858 lightsalmon: 0xffa07a,
22859 lightseagreen: 0x20b2aa,
22860 lightskyblue: 0x87cefa,
22861 lightslategray: 0x778899,
22862 lightslategrey: 0x778899,
22863 lightsteelblue: 0xb0c4de,
22864 lightyellow: 0xffffe0,
22866 limegreen: 0x32cd32,
22870 mediumaquamarine: 0x66cdaa,
22871 mediumblue: 0x0000cd,
22872 mediumorchid: 0xba55d3,
22873 mediumpurple: 0x9370db,
22874 mediumseagreen: 0x3cb371,
22875 mediumslateblue: 0x7b68ee,
22876 mediumspringgreen: 0x00fa9a,
22877 mediumturquoise: 0x48d1cc,
22878 mediumvioletred: 0xc71585,
22879 midnightblue: 0x191970,
22880 mintcream: 0xf5fffa,
22881 mistyrose: 0xffe4e1,
22882 moccasin: 0xffe4b5,
22883 navajowhite: 0xffdead,
22887 olivedrab: 0x6b8e23,
22889 orangered: 0xff4500,
22891 palegoldenrod: 0xeee8aa,
22892 palegreen: 0x98fb98,
22893 paleturquoise: 0xafeeee,
22894 palevioletred: 0xdb7093,
22895 papayawhip: 0xffefd5,
22896 peachpuff: 0xffdab9,
22900 powderblue: 0xb0e0e6,
22902 rebeccapurple: 0x663399,
22904 rosybrown: 0xbc8f8f,
22905 royalblue: 0x4169e1,
22906 saddlebrown: 0x8b4513,
22908 sandybrown: 0xf4a460,
22909 seagreen: 0x2e8b57,
22910 seashell: 0xfff5ee,
22914 slateblue: 0x6a5acd,
22915 slategray: 0x708090,
22916 slategrey: 0x708090,
22918 springgreen: 0x00ff7f,
22919 steelblue: 0x4682b4,
22924 turquoise: 0x40e0d0,
22928 whitesmoke: 0xf5f5f5,
22930 yellowgreen: 0x9acd32
22933 define$1(Color, color, {
22934 displayable: function() {
22935 return this.rgb().displayable();
22937 toString: function() {
22938 return this.rgb() + "";
22942 function color(format) {
22944 format = (format + "").trim().toLowerCase();
22945 return (m = reHex3.exec(format)) ? (m = parseInt(m[1], 16), new Rgb((m >> 8 & 0xf) | (m >> 4 & 0x0f0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1)) // #f00
22946 : (m = reHex6.exec(format)) ? rgbn(parseInt(m[1], 16)) // #ff0000
22947 : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)
22948 : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)
22949 : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)
22950 : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)
22951 : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)
22952 : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)
22953 : named.hasOwnProperty(format) ? rgbn(named[format])
22954 : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0)
22959 return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);
22962 function rgba(r, g, b, a) {
22963 if (a <= 0) r = g = b = NaN;
22964 return new Rgb(r, g, b, a);
22967 function rgbConvert(o) {
22968 if (!(o instanceof Color)) o = color(o);
22969 if (!o) return new Rgb;
22971 return new Rgb(o.r, o.g, o.b, o.opacity);
22974 function rgb(r, g, b, opacity) {
22975 return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);
22978 function Rgb(r, g, b, opacity) {
22982 this.opacity = +opacity;
22985 define$1(Rgb, rgb, extend(Color, {
22986 brighter: function(k) {
22987 k = k == null ? brighter : Math.pow(brighter, k);
22988 return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
22990 darker: function(k) {
22991 k = k == null ? darker : Math.pow(darker, k);
22992 return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
22997 displayable: function() {
22998 return (0 <= this.r && this.r <= 255)
22999 && (0 <= this.g && this.g <= 255)
23000 && (0 <= this.b && this.b <= 255)
23001 && (0 <= this.opacity && this.opacity <= 1);
23003 toString: function() {
23004 var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
23005 return (a === 1 ? "rgb(" : "rgba(")
23006 + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", "
23007 + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", "
23008 + Math.max(0, Math.min(255, Math.round(this.b) || 0))
23009 + (a === 1 ? ")" : ", " + a + ")");
23013 function hsla(h, s, l, a) {
23014 if (a <= 0) h = s = l = NaN;
23015 else if (l <= 0 || l >= 1) h = s = NaN;
23016 else if (s <= 0) h = NaN;
23017 return new Hsl(h, s, l, a);
23020 function hslConvert(o) {
23021 if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);
23022 if (!(o instanceof Color)) o = color(o);
23023 if (!o) return new Hsl;
23024 if (o instanceof Hsl) return o;
23029 min = Math.min(r, g, b),
23030 max = Math.max(r, g, b),
23033 l = (max + min) / 2;
23035 if (r === max) h = (g - b) / s + (g < b) * 6;
23036 else if (g === max) h = (b - r) / s + 2;
23037 else h = (r - g) / s + 4;
23038 s /= l < 0.5 ? max + min : 2 - max - min;
23041 s = l > 0 && l < 1 ? 0 : h;
23043 return new Hsl(h, s, l, o.opacity);
23046 function hsl(h, s, l, opacity) {
23047 return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);
23050 function Hsl(h, s, l, opacity) {
23054 this.opacity = +opacity;
23057 define$1(Hsl, hsl, extend(Color, {
23058 brighter: function(k) {
23059 k = k == null ? brighter : Math.pow(brighter, k);
23060 return new Hsl(this.h, this.s, this.l * k, this.opacity);
23062 darker: function(k) {
23063 k = k == null ? darker : Math.pow(darker, k);
23064 return new Hsl(this.h, this.s, this.l * k, this.opacity);
23067 var h = this.h % 360 + (this.h < 0) * 360,
23068 s = isNaN(h) || isNaN(this.s) ? 0 : this.s,
23070 m2 = l + (l < 0.5 ? l : 1 - l) * s,
23073 hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),
23074 hsl2rgb(h, m1, m2),
23075 hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),
23079 displayable: function() {
23080 return (0 <= this.s && this.s <= 1 || isNaN(this.s))
23081 && (0 <= this.l && this.l <= 1)
23082 && (0 <= this.opacity && this.opacity <= 1);
23086 /* From FvD 13.37, CSS Color Module Level 3 */
23087 function hsl2rgb(h, m1, m2) {
23088 return (h < 60 ? m1 + (m2 - m1) * h / 60
23090 : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60
23094 var deg2rad = Math.PI / 180;
23095 var rad2deg = 180 / Math.PI;
23103 var t2 = 3 * t1 * t1;
23104 var t3 = t1 * t1 * t1;
23106 function labConvert(o) {
23107 if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity);
23108 if (o instanceof Hcl) {
23109 var h = o.h * deg2rad;
23110 return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity);
23112 if (!(o instanceof Rgb)) o = rgbConvert(o);
23113 var b = rgb2xyz(o.r),
23116 x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn),
23117 y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.0721750 * l) / Yn),
23118 z = xyz2lab((0.0193339 * b + 0.1191920 * a + 0.9503041 * l) / Zn);
23119 return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity);
23122 function lab(l, a, b, opacity) {
23123 return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity);
23126 function Lab(l, a, b, opacity) {
23130 this.opacity = +opacity;
23133 define$1(Lab, lab, extend(Color, {
23134 brighter: function(k) {
23135 return new Lab(this.l + Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);
23137 darker: function(k) {
23138 return new Lab(this.l - Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);
23141 var y = (this.l + 16) / 116,
23142 x = isNaN(this.a) ? y : y + this.a / 500,
23143 z = isNaN(this.b) ? y : y - this.b / 200;
23144 y = Yn * lab2xyz(y);
23145 x = Xn * lab2xyz(x);
23146 z = Zn * lab2xyz(z);
23148 xyz2rgb( 3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB
23149 xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z),
23150 xyz2rgb( 0.0556434 * x - 0.2040259 * y + 1.0572252 * z),
23156 function xyz2lab(t) {
23157 return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0;
23160 function lab2xyz(t) {
23161 return t > t1 ? t * t * t : t2 * (t - t0);
23164 function xyz2rgb(x) {
23165 return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055);
23168 function rgb2xyz(x) {
23169 return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
23172 function hclConvert(o) {
23173 if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity);
23174 if (!(o instanceof Lab)) o = labConvert(o);
23175 var h = Math.atan2(o.b, o.a) * rad2deg;
23176 return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity);
23179 function hcl(h, c, l, opacity) {
23180 return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity);
23183 function Hcl(h, c, l, opacity) {
23187 this.opacity = +opacity;
23190 define$1(Hcl, hcl, extend(Color, {
23191 brighter: function(k) {
23192 return new Hcl(this.h, this.c, this.l + Kn * (k == null ? 1 : k), this.opacity);
23194 darker: function(k) {
23195 return new Hcl(this.h, this.c, this.l - Kn * (k == null ? 1 : k), this.opacity);
23198 return labConvert(this).rgb();
23209 var BC_DA = B * C - D * A;
23211 function cubehelixConvert(o) {
23212 if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity);
23213 if (!(o instanceof Rgb)) o = rgbConvert(o);
23217 l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB),
23219 k = (E * (g - l) - C * bl) / D,
23220 s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1
23221 h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN;
23222 return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity);
23225 function cubehelix(h, s, l, opacity) {
23226 return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity);
23229 function Cubehelix(h, s, l, opacity) {
23233 this.opacity = +opacity;
23236 define$1(Cubehelix, cubehelix, extend(Color, {
23237 brighter: function(k) {
23238 k = k == null ? brighter : Math.pow(brighter, k);
23239 return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
23241 darker: function(k) {
23242 k = k == null ? darker : Math.pow(darker, k);
23243 return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
23246 var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad,
23248 a = isNaN(this.s) ? 0 : this.s * l * (1 - l),
23249 cosh = Math.cos(h),
23250 sinh = Math.sin(h);
23252 255 * (l + a * (A * cosh + B * sinh)),
23253 255 * (l + a * (C * cosh + D * sinh)),
23254 255 * (l + a * (E * cosh)),
23260 function basis$1(t1, v0, v1, v2, v3) {
23261 var t2 = t1 * t1, t3 = t2 * t1;
23262 return ((1 - 3 * t1 + 3 * t2 - t3) * v0
23263 + (4 - 6 * t2 + 3 * t3) * v1
23264 + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2
23268 var basis$2 = function(values) {
23269 var n = values.length - 1;
23270 return function(t) {
23271 var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n),
23273 v2 = values[i + 1],
23274 v0 = i > 0 ? values[i - 1] : 2 * v1 - v2,
23275 v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1;
23276 return basis$1((t - i / n) * n, v0, v1, v2, v3);
23280 var basisClosed$1 = function(values) {
23281 var n = values.length;
23282 return function(t) {
23283 var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n),
23284 v0 = values[(i + n - 1) % n],
23285 v1 = values[i % n],
23286 v2 = values[(i + 1) % n],
23287 v3 = values[(i + 2) % n];
23288 return basis$1((t - i / n) * n, v0, v1, v2, v3);
23292 var constant$3 = function(x) {
23293 return function() {
23298 function linear$1(a, d) {
23299 return function(t) {
23304 function exponential$1(a, b, y) {
23305 return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {
23306 return Math.pow(a + t * b, y);
23310 function hue(a, b) {
23312 return d ? linear$1(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant$3(isNaN(a) ? b : a);
23315 function gamma(y) {
23316 return (y = +y) === 1 ? nogamma : function(a, b) {
23317 return b - a ? exponential$1(a, b, y) : constant$3(isNaN(a) ? b : a);
23321 function nogamma(a, b) {
23323 return d ? linear$1(a, d) : constant$3(isNaN(a) ? b : a);
23326 var interpolateRgb = (function rgbGamma(y) {
23327 var color$$1 = gamma(y);
23329 function rgb$$1(start, end) {
23330 var r = color$$1((start = rgb(start)).r, (end = rgb(end)).r),
23331 g = color$$1(start.g, end.g),
23332 b = color$$1(start.b, end.b),
23333 opacity = color$$1(start.opacity, end.opacity);
23334 return function(t) {
23338 start.opacity = opacity(t);
23343 rgb$$1.gamma = rgbGamma;
23348 function rgbSpline(spline) {
23349 return function(colors) {
23350 var n = colors.length,
23355 for (i = 0; i < n; ++i) {
23356 color$$1 = rgb(colors[i]);
23357 r[i] = color$$1.r || 0;
23358 g[i] = color$$1.g || 0;
23359 b[i] = color$$1.b || 0;
23364 color$$1.opacity = 1;
23365 return function(t) {
23369 return color$$1 + "";
23374 var rgbBasis = rgbSpline(basis$2);
23375 var rgbBasisClosed = rgbSpline(basisClosed$1);
23377 var array$1 = function(a, b) {
23378 var nb = b ? b.length : 0,
23379 na = a ? Math.min(nb, a.length) : 0,
23384 for (i = 0; i < na; ++i) x[i] = interpolate(a[i], b[i]);
23385 for (; i < nb; ++i) c[i] = b[i];
23387 return function(t) {
23388 for (i = 0; i < na; ++i) c[i] = x[i](t);
23393 var date = function(a, b) {
23395 return a = +a, b -= a, function(t) {
23396 return d.setTime(a + b * t), d;
23400 var interpolateNumber = function(a, b) {
23401 return a = +a, b -= a, function(t) {
23406 var object = function(a, b) {
23411 if (a === null || typeof a !== "object") a = {};
23412 if (b === null || typeof b !== "object") b = {};
23416 i[k] = interpolate(a[k], b[k]);
23422 return function(t) {
23423 for (k in i) c[k] = i[k](t);
23428 var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;
23429 var reB = new RegExp(reA.source, "g");
23432 return function() {
23438 return function(t) {
23443 var interpolateString = function(a, b) {
23444 var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b
23445 am, // current match in a
23446 bm, // current match in b
23447 bs, // string preceding current number in b, if any
23448 i = -1, // index in s
23449 s = [], // string constants and placeholders
23450 q = []; // number interpolators
23452 // Coerce inputs to strings.
23453 a = a + "", b = b + "";
23455 // Interpolate pairs of numbers in a & b.
23456 while ((am = reA.exec(a))
23457 && (bm = reB.exec(b))) {
23458 if ((bs = bm.index) > bi) { // a string precedes the next number in b
23459 bs = b.slice(bi, bs);
23460 if (s[i]) s[i] += bs; // coalesce with previous string
23463 if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match
23464 if (s[i]) s[i] += bm; // coalesce with previous string
23466 } else { // interpolate non-matching numbers
23468 q.push({i: i, x: interpolateNumber(am, bm)});
23470 bi = reB.lastIndex;
23473 // Add remains of b.
23474 if (bi < b.length) {
23476 if (s[i]) s[i] += bs; // coalesce with previous string
23480 // Special optimization for only a single match.
23481 // Otherwise, interpolate each of the numbers and rejoin the string.
23482 return s.length < 2 ? (q[0]
23485 : (b = q.length, function(t) {
23486 for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);
23491 var interpolate = function(a, b) {
23492 var t = typeof b, c;
23493 return b == null || t === "boolean" ? constant$3(b)
23494 : (t === "number" ? interpolateNumber
23495 : t === "string" ? ((c = color(b)) ? (b = c, interpolateRgb) : interpolateString)
23496 : b instanceof color ? interpolateRgb
23497 : b instanceof Date ? date
23498 : Array.isArray(b) ? array$1
23499 : isNaN(b) ? object
23500 : interpolateNumber)(a, b);
23503 var interpolateRound = function(a, b) {
23504 return a = +a, b -= a, function(t) {
23505 return Math.round(a + b * t);
23509 var degrees = 180 / Math.PI;
23520 var decompose = function(a, b, c, d, e, f) {
23521 var scaleX, scaleY, skewX;
23522 if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;
23523 if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;
23524 if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;
23525 if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;
23529 rotate: Math.atan2(b, a) * degrees,
23530 skewX: Math.atan(skewX) * degrees,
23541 function parseCss(value) {
23542 if (value === "none") return identity$2;
23543 if (!cssNode) cssNode = document.createElement("DIV"), cssRoot = document.documentElement, cssView = document.defaultView;
23544 cssNode.style.transform = value;
23545 value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue("transform");
23546 cssRoot.removeChild(cssNode);
23547 value = value.slice(7, -1).split(",");
23548 return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]);
23551 function parseSvg(value) {
23552 if (value == null) return identity$2;
23553 if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g");
23554 svgNode.setAttribute("transform", value);
23555 if (!(value = svgNode.transform.baseVal.consolidate())) return identity$2;
23556 value = value.matrix;
23557 return decompose(value.a, value.b, value.c, value.d, value.e, value.f);
23560 function interpolateTransform(parse, pxComma, pxParen, degParen) {
23563 return s.length ? s.pop() + " " : "";
23566 function translate(xa, ya, xb, yb, s, q) {
23567 if (xa !== xb || ya !== yb) {
23568 var i = s.push("translate(", null, pxComma, null, pxParen);
23569 q.push({i: i - 4, x: interpolateNumber(xa, xb)}, {i: i - 2, x: interpolateNumber(ya, yb)});
23570 } else if (xb || yb) {
23571 s.push("translate(" + xb + pxComma + yb + pxParen);
23575 function rotate(a, b, s, q) {
23577 if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path
23578 q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: interpolateNumber(a, b)});
23580 s.push(pop(s) + "rotate(" + b + degParen);
23584 function skewX(a, b, s, q) {
23586 q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: interpolateNumber(a, b)});
23588 s.push(pop(s) + "skewX(" + b + degParen);
23592 function scale(xa, ya, xb, yb, s, q) {
23593 if (xa !== xb || ya !== yb) {
23594 var i = s.push(pop(s) + "scale(", null, ",", null, ")");
23595 q.push({i: i - 4, x: interpolateNumber(xa, xb)}, {i: i - 2, x: interpolateNumber(ya, yb)});
23596 } else if (xb !== 1 || yb !== 1) {
23597 s.push(pop(s) + "scale(" + xb + "," + yb + ")");
23601 return function(a, b) {
23602 var s = [], // string constants and placeholders
23603 q = []; // number interpolators
23604 a = parse(a), b = parse(b);
23605 translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);
23606 rotate(a.rotate, b.rotate, s, q);
23607 skewX(a.skewX, b.skewX, s, q);
23608 scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);
23609 a = b = null; // gc
23610 return function(t) {
23611 var i = -1, n = q.length, o;
23612 while (++i < n) s[(o = q[i]).i] = o.x(t);
23618 var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)");
23619 var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")");
23621 var rho = Math.SQRT2;
23624 var epsilon2 = 1e-12;
23627 return ((x = Math.exp(x)) + 1 / x) / 2;
23631 return ((x = Math.exp(x)) - 1 / x) / 2;
23635 return ((x = Math.exp(2 * x)) - 1) / (x + 1);
23638 // p0 = [ux0, uy0, w0]
23639 // p1 = [ux1, uy1, w1]
23640 var interpolateZoom = function(p0, p1) {
23641 var ux0 = p0[0], uy0 = p0[1], w0 = p0[2],
23642 ux1 = p1[0], uy1 = p1[1], w1 = p1[2],
23645 d2 = dx * dx + dy * dy,
23649 // Special case for u0 ≅ u1.
23650 if (d2 < epsilon2) {
23651 S = Math.log(w1 / w0) / rho;
23656 w0 * Math.exp(rho * t * S)
23663 var d1 = Math.sqrt(d2),
23664 b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1),
23665 b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1),
23666 r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0),
23667 r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);
23668 S = (r1 - r0) / rho;
23672 u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));
23676 w0 * coshr0 / cosh(rho * s + r0)
23681 i.duration = S * 1000;
23686 function hsl$1(hue$$1) {
23687 return function(start, end) {
23688 var h = hue$$1((start = hsl(start)).h, (end = hsl(end)).h),
23689 s = nogamma(start.s, end.s),
23690 l = nogamma(start.l, end.l),
23691 opacity = nogamma(start.opacity, end.opacity);
23692 return function(t) {
23696 start.opacity = opacity(t);
23702 var hsl$2 = hsl$1(hue);
23703 var hslLong = hsl$1(nogamma);
23705 function lab$1(start, end) {
23706 var l = nogamma((start = lab(start)).l, (end = lab(end)).l),
23707 a = nogamma(start.a, end.a),
23708 b = nogamma(start.b, end.b),
23709 opacity = nogamma(start.opacity, end.opacity);
23710 return function(t) {
23714 start.opacity = opacity(t);
23719 function hcl$1(hue$$1) {
23720 return function(start, end) {
23721 var h = hue$$1((start = hcl(start)).h, (end = hcl(end)).h),
23722 c = nogamma(start.c, end.c),
23723 l = nogamma(start.l, end.l),
23724 opacity = nogamma(start.opacity, end.opacity);
23725 return function(t) {
23729 start.opacity = opacity(t);
23735 var hcl$2 = hcl$1(hue);
23736 var hclLong = hcl$1(nogamma);
23738 function cubehelix$1(hue$$1) {
23739 return (function cubehelixGamma(y) {
23742 function cubehelix$$1(start, end) {
23743 var h = hue$$1((start = cubehelix(start)).h, (end = cubehelix(end)).h),
23744 s = nogamma(start.s, end.s),
23745 l = nogamma(start.l, end.l),
23746 opacity = nogamma(start.opacity, end.opacity);
23747 return function(t) {
23750 start.l = l(Math.pow(t, y));
23751 start.opacity = opacity(t);
23756 cubehelix$$1.gamma = cubehelixGamma;
23758 return cubehelix$$1;
23762 var cubehelix$2 = cubehelix$1(hue);
23763 var cubehelixLong = cubehelix$1(nogamma);
23765 var quantize = function(interpolator, n) {
23766 var samples = new Array(n);
23767 for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1));
23771 var noop$1 = {value: function() {}};
23773 function dispatch() {
23774 for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {
23775 if (!(t = arguments[i] + "") || (t in _)) throw new Error("illegal type: " + t);
23778 return new Dispatch(_);
23781 function Dispatch(_) {
23785 function parseTypenames(typenames, types) {
23786 return typenames.trim().split(/^|\s+/).map(function(t) {
23787 var name = "", i = t.indexOf(".");
23788 if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
23789 if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t);
23790 return {type: t, name: name};
23794 Dispatch.prototype = dispatch.prototype = {
23795 constructor: Dispatch,
23796 on: function(typename, callback) {
23798 T = parseTypenames(typename + "", _),
23803 // If no callback was specified, return the callback of the given type and name.
23804 if (arguments.length < 2) {
23805 while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;
23809 // If a type was specified, set the callback for the given type and name.
23810 // Otherwise, if a null callback was specified, remove callbacks of the given name.
23811 if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback);
23813 if (t = (typename = T[i]).type) _[t] = set$2(_[t], typename.name, callback);
23814 else if (callback == null) for (t in _) _[t] = set$2(_[t], typename.name, null);
23820 var copy = {}, _ = this._;
23821 for (var t in _) copy[t] = _[t].slice();
23822 return new Dispatch(copy);
23824 call: function(type, that) {
23825 if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];
23826 if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
23827 for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
23829 apply: function(type, that, args) {
23830 if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
23831 for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
23835 function get(type, name) {
23836 for (var i = 0, n = type.length, c; i < n; ++i) {
23837 if ((c = type[i]).name === name) {
23843 function set$2(type, name, callback) {
23844 for (var i = 0, n = type.length; i < n; ++i) {
23845 if (type[i].name === name) {
23846 type[i] = noop$1, type = type.slice(0, i).concat(type.slice(i + 1));
23850 if (callback != null) type.push({name: name, value: callback});
23854 function objectConverter(columns) {
23855 return new Function("d", "return {" + columns.map(function(name, i) {
23856 return JSON.stringify(name) + ": d[" + i + "]";
23857 }).join(",") + "}");
23860 function customConverter(columns, f) {
23861 var object = objectConverter(columns);
23862 return function(row, i) {
23863 return f(object(row), i, columns);
23867 // Compute unique columns in order of discovery.
23868 function inferColumns(rows) {
23869 var columnSet = Object.create(null),
23872 rows.forEach(function(row) {
23873 for (var column in row) {
23874 if (!(column in columnSet)) {
23875 columns.push(columnSet[column] = column);
23883 var dsv = function(delimiter) {
23884 var reFormat = new RegExp("[\"" + delimiter + "\n]"),
23885 delimiterCode = delimiter.charCodeAt(0);
23887 function parse(text, f) {
23888 var convert, columns, rows = parseRows(text, function(row, i) {
23889 if (convert) return convert(row, i - 1);
23890 columns = row, convert = f ? customConverter(row, f) : objectConverter(row);
23892 rows.columns = columns;
23896 function parseRows(text, f) {
23897 var EOL = {}, // sentinel value for end-of-line
23898 EOF = {}, // sentinel value for end-of-file
23899 rows = [], // output rows
23901 I = 0, // current character index
23902 n = 0, // the current line number
23903 t, // the current token
23904 eol; // is the current token followed by EOL?
23907 if (I >= N) return EOF; // special case: end of file
23908 if (eol) return eol = false, EOL; // special case: end of line
23910 // special case: quotes
23912 if (text.charCodeAt(j) === 34) {
23915 if (text.charCodeAt(i) === 34) {
23916 if (text.charCodeAt(i + 1) !== 34) break;
23921 c = text.charCodeAt(i + 1);
23924 if (text.charCodeAt(i + 2) === 10) ++I;
23925 } else if (c === 10) {
23928 return text.slice(j + 1, i).replace(/""/g, "\"");
23931 // common case: find next delimiter or newline
23934 c = text.charCodeAt(I++);
23935 if (c === 10) eol = true; // \n
23936 else if (c === 13) { eol = true; if (text.charCodeAt(I) === 10) ++I, ++k; } // \r|\r\n
23937 else if (c !== delimiterCode) continue;
23938 return text.slice(j, I - k);
23941 // special case: last token before EOF
23942 return text.slice(j);
23945 while ((t = token()) !== EOF) {
23947 while (t !== EOL && t !== EOF) {
23951 if (f && (a = f(a, n++)) == null) continue;
23958 function format(rows, columns) {
23959 if (columns == null) columns = inferColumns(rows);
23960 return [columns.map(formatValue).join(delimiter)].concat(rows.map(function(row) {
23961 return columns.map(function(column) {
23962 return formatValue(row[column]);
23963 }).join(delimiter);
23967 function formatRows(rows) {
23968 return rows.map(formatRow).join("\n");
23971 function formatRow(row) {
23972 return row.map(formatValue).join(delimiter);
23975 function formatValue(text) {
23976 return text == null ? ""
23977 : reFormat.test(text += "") ? "\"" + text.replace(/\"/g, "\"\"") + "\""
23983 parseRows: parseRows,
23985 formatRows: formatRows
23989 var csv = dsv(",");
23991 var csvParse = csv.parse;
23992 var csvParseRows = csv.parseRows;
23993 var csvFormat = csv.format;
23994 var csvFormatRows = csv.formatRows;
23996 var tsv = dsv("\t");
23998 var tsvParse = tsv.parse;
23999 var tsvParseRows = tsv.parseRows;
24000 var tsvFormat = tsv.format;
24001 var tsvFormatRows = tsv.formatRows;
24003 var request = function(url, callback) {
24005 event = dispatch("beforesend", "progress", "load", "error"),
24008 xhr = new XMLHttpRequest,
24015 // If IE does not support CORS, use XDomainRequest.
24016 if (typeof XDomainRequest !== "undefined"
24017 && !("withCredentials" in xhr)
24018 && /^(http(s)?:)?\/\//.test(url)) xhr = new XDomainRequest;
24021 ? xhr.onload = xhr.onerror = xhr.ontimeout = respond
24022 : xhr.onreadystatechange = function(o) { xhr.readyState > 3 && respond(o); };
24024 function respond(o) {
24025 var status = xhr.status, result;
24026 if (!status && hasResponse(xhr)
24027 || status >= 200 && status < 300
24028 || status === 304) {
24031 result = response.call(request, xhr);
24033 event.call("error", request, e);
24039 event.call("load", request, result);
24041 event.call("error", request, o);
24045 xhr.onprogress = function(e) {
24046 event.call("progress", request, e);
24050 header: function(name, value) {
24051 name = (name + "").toLowerCase();
24052 if (arguments.length < 2) return headers.get(name);
24053 if (value == null) headers.remove(name);
24054 else headers.set(name, value + "");
24058 // If mimeType is non-null and no Accept header is set, a default is used.
24059 mimeType: function(value) {
24060 if (!arguments.length) return mimeType;
24061 mimeType = value == null ? null : value + "";
24065 // Specifies what type the response value should take;
24066 // for instance, arraybuffer, blob, document, or text.
24067 responseType: function(value) {
24068 if (!arguments.length) return responseType;
24069 responseType = value;
24073 timeout: function(value) {
24074 if (!arguments.length) return timeout;
24079 user: function(value) {
24080 return arguments.length < 1 ? user : (user = value == null ? null : value + "", request);
24083 password: function(value) {
24084 return arguments.length < 1 ? password : (password = value == null ? null : value + "", request);
24087 // Specify how to convert the response content to a specific type;
24088 // changes the callback value on "load" events.
24089 response: function(value) {
24094 // Alias for send("GET", …).
24095 get: function(data, callback) {
24096 return request.send("GET", data, callback);
24099 // Alias for send("POST", …).
24100 post: function(data, callback) {
24101 return request.send("POST", data, callback);
24104 // If callback is non-null, it will be used for error and load events.
24105 send: function(method, data, callback) {
24106 xhr.open(method, url, true, user, password);
24107 if (mimeType != null && !headers.has("accept")) headers.set("accept", mimeType + ",*/*");
24108 if (xhr.setRequestHeader) headers.each(function(value, name) { xhr.setRequestHeader(name, value); });
24109 if (mimeType != null && xhr.overrideMimeType) xhr.overrideMimeType(mimeType);
24110 if (responseType != null) xhr.responseType = responseType;
24111 if (timeout > 0) xhr.timeout = timeout;
24112 if (callback == null && typeof data === "function") callback = data, data = null;
24113 if (callback != null && callback.length === 1) callback = fixCallback(callback);
24114 if (callback != null) request.on("error", callback).on("load", function(xhr) { callback(null, xhr); });
24115 event.call("beforesend", request, xhr);
24116 xhr.send(data == null ? null : data);
24120 abort: function() {
24126 var value = event.on.apply(event, arguments);
24127 return value === event ? request : value;
24131 if (callback != null) {
24132 if (typeof callback !== "function") throw new Error("invalid callback: " + callback);
24133 return request.get(callback);
24139 function fixCallback(callback) {
24140 return function(error, xhr) {
24141 callback(error == null ? xhr : null);
24145 function hasResponse(xhr) {
24146 var type = xhr.responseType;
24147 return type && type !== "text"
24148 ? xhr.response // null on error
24149 : xhr.responseText; // "" on error
24152 var type$2 = function(defaultMimeType, response) {
24153 return function(url, callback) {
24154 var r = request(url).mimeType(defaultMimeType).response(response);
24155 if (callback != null) {
24156 if (typeof callback !== "function") throw new Error("invalid callback: " + callback);
24157 return r.get(callback);
24163 var html = type$2("text/html", function(xhr) {
24164 return document.createRange().createContextualFragment(xhr.responseText);
24167 var json = type$2("application/json", function(xhr) {
24168 return JSON.parse(xhr.responseText);
24171 var text = type$2("text/plain", function(xhr) {
24172 return xhr.responseText;
24175 var xml = type$2("application/xml", function(xhr) {
24176 var xml = xhr.responseXML;
24177 if (!xml) throw new Error("parse error");
24181 var dsv$1 = function(defaultMimeType, parse) {
24182 return function(url, row, callback) {
24183 if (arguments.length < 3) callback = row, row = null;
24184 var r = request(url).mimeType(defaultMimeType);
24185 r.row = function(_) { return arguments.length ? r.response(responseOf(parse, row = _)) : row; };
24187 return callback ? r.get(callback) : r;
24191 function responseOf(parse, row) {
24192 return function(request$$1) {
24193 return parse(request$$1.responseText, row);
24197 var csv$1 = dsv$1("text/csv", csvParse);
24199 var tsv$1 = dsv$1("text/tab-separated-values", tsvParse);
24204 var pokeDelay = 1000;
24210 var clock = typeof performance === "object" && performance.now ? performance : Date;
24211 var setFrame = typeof requestAnimationFrame === "function" ? requestAnimationFrame : function(f) { setTimeout(f, 17); };
24214 return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);
24217 function clearNow() {
24227 Timer.prototype = timer.prototype = {
24228 constructor: Timer,
24229 restart: function(callback, delay, time) {
24230 if (typeof callback !== "function") throw new TypeError("callback is not a function");
24231 time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);
24232 if (!this._next && taskTail !== this) {
24233 if (taskTail) taskTail._next = this;
24234 else taskHead = this;
24237 this._call = callback;
24244 this._time = Infinity;
24250 function timer(callback, delay, time) {
24252 t.restart(callback, delay, time);
24256 function timerFlush() {
24257 now(); // Get the current time, if not already set.
24258 ++frame; // Pretend we’ve set an alarm, if we haven’t already.
24259 var t = taskHead, e;
24261 if ((e = clockNow - t._time) >= 0) t._call.call(null, e);
24268 clockNow = (clockLast = clock.now()) + clockSkew;
24269 frame = timeout = 0;
24279 function poke$1() {
24280 var now = clock.now(), delay = now - clockLast;
24281 if (delay > pokeDelay) clockSkew -= delay, clockLast = now;
24285 var t0, t1 = taskHead, t2, time = Infinity;
24288 if (time > t1._time) time = t1._time;
24289 t0 = t1, t1 = t1._next;
24291 t2 = t1._next, t1._next = null;
24292 t1 = t0 ? t0._next = t2 : taskHead = t2;
24299 function sleep(time) {
24300 if (frame) return; // Soonest alarm already set, or will be.
24301 if (timeout) timeout = clearTimeout(timeout);
24302 var delay = time - clockNow;
24304 if (time < Infinity) timeout = setTimeout(wake, delay);
24305 if (interval) interval = clearInterval(interval);
24307 if (!interval) interval = setInterval(poke$1, pokeDelay);
24308 frame = 1, setFrame(wake);
24312 var timeout$1 = function(callback, delay, time) {
24314 delay = delay == null ? 0 : +delay;
24315 t.restart(function(elapsed) {
24317 callback(elapsed + delay);
24322 var interval$1 = function(callback, delay, time) {
24323 var t = new Timer, total = delay;
24324 if (delay == null) return t.restart(callback, delay, time), t;
24325 delay = +delay, time = time == null ? now() : +time;
24326 t.restart(function tick(elapsed) {
24328 t.restart(tick, total += delay, time);
24334 var t0$1 = new Date;
24335 var t1$1 = new Date;
24337 function newInterval(floori, offseti, count, field) {
24339 function interval(date) {
24340 return floori(date = new Date(+date)), date;
24343 interval.floor = interval;
24345 interval.ceil = function(date) {
24346 return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;
24349 interval.round = function(date) {
24350 var d0 = interval(date),
24351 d1 = interval.ceil(date);
24352 return date - d0 < d1 - date ? d0 : d1;
24355 interval.offset = function(date, step) {
24356 return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;
24359 interval.range = function(start, stop, step) {
24361 start = interval.ceil(start);
24362 step = step == null ? 1 : Math.floor(step);
24363 if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date
24364 do range.push(new Date(+start)); while (offseti(start, step), floori(start), start < stop)
24368 interval.filter = function(test) {
24369 return newInterval(function(date) {
24370 if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1);
24371 }, function(date, step) {
24372 if (date >= date) while (--step >= 0) while (offseti(date, 1), !test(date)) {} // eslint-disable-line no-empty
24377 interval.count = function(start, end) {
24378 t0$1.setTime(+start), t1$1.setTime(+end);
24379 floori(t0$1), floori(t1$1);
24380 return Math.floor(count(t0$1, t1$1));
24383 interval.every = function(step) {
24384 step = Math.floor(step);
24385 return !isFinite(step) || !(step > 0) ? null
24386 : !(step > 1) ? interval
24387 : interval.filter(field
24388 ? function(d) { return field(d) % step === 0; }
24389 : function(d) { return interval.count(0, d) % step === 0; });
24396 var millisecond = newInterval(function() {
24398 }, function(date, step) {
24399 date.setTime(+date + step);
24400 }, function(start, end) {
24401 return end - start;
24404 // An optimized implementation for this simple case.
24405 millisecond.every = function(k) {
24407 if (!isFinite(k) || !(k > 0)) return null;
24408 if (!(k > 1)) return millisecond;
24409 return newInterval(function(date) {
24410 date.setTime(Math.floor(date / k) * k);
24411 }, function(date, step) {
24412 date.setTime(+date + step * k);
24413 }, function(start, end) {
24414 return (end - start) / k;
24418 var milliseconds = millisecond.range;
24420 var durationSecond = 1e3;
24421 var durationMinute = 6e4;
24422 var durationHour = 36e5;
24423 var durationDay = 864e5;
24424 var durationWeek = 6048e5;
24426 var second = newInterval(function(date) {
24427 date.setTime(Math.floor(date / durationSecond) * durationSecond);
24428 }, function(date, step) {
24429 date.setTime(+date + step * durationSecond);
24430 }, function(start, end) {
24431 return (end - start) / durationSecond;
24432 }, function(date) {
24433 return date.getUTCSeconds();
24436 var seconds = second.range;
24438 var minute = newInterval(function(date) {
24439 date.setTime(Math.floor(date / durationMinute) * durationMinute);
24440 }, function(date, step) {
24441 date.setTime(+date + step * durationMinute);
24442 }, function(start, end) {
24443 return (end - start) / durationMinute;
24444 }, function(date) {
24445 return date.getMinutes();
24448 var minutes = minute.range;
24450 var hour = newInterval(function(date) {
24451 var offset = date.getTimezoneOffset() * durationMinute % durationHour;
24452 if (offset < 0) offset += durationHour;
24453 date.setTime(Math.floor((+date - offset) / durationHour) * durationHour + offset);
24454 }, function(date, step) {
24455 date.setTime(+date + step * durationHour);
24456 }, function(start, end) {
24457 return (end - start) / durationHour;
24458 }, function(date) {
24459 return date.getHours();
24462 var hours = hour.range;
24464 var day = newInterval(function(date) {
24465 date.setHours(0, 0, 0, 0);
24466 }, function(date, step) {
24467 date.setDate(date.getDate() + step);
24468 }, function(start, end) {
24469 return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationDay;
24470 }, function(date) {
24471 return date.getDate() - 1;
24474 var days = day.range;
24476 function weekday(i) {
24477 return newInterval(function(date) {
24478 date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);
24479 date.setHours(0, 0, 0, 0);
24480 }, function(date, step) {
24481 date.setDate(date.getDate() + step * 7);
24482 }, function(start, end) {
24483 return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationWeek;
24487 var sunday = weekday(0);
24488 var monday = weekday(1);
24489 var tuesday = weekday(2);
24490 var wednesday = weekday(3);
24491 var thursday = weekday(4);
24492 var friday = weekday(5);
24493 var saturday = weekday(6);
24495 var sundays = sunday.range;
24496 var mondays = monday.range;
24497 var tuesdays = tuesday.range;
24498 var wednesdays = wednesday.range;
24499 var thursdays = thursday.range;
24500 var fridays = friday.range;
24501 var saturdays = saturday.range;
24503 var month = newInterval(function(date) {
24505 date.setHours(0, 0, 0, 0);
24506 }, function(date, step) {
24507 date.setMonth(date.getMonth() + step);
24508 }, function(start, end) {
24509 return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;
24510 }, function(date) {
24511 return date.getMonth();
24514 var months = month.range;
24516 var year = newInterval(function(date) {
24517 date.setMonth(0, 1);
24518 date.setHours(0, 0, 0, 0);
24519 }, function(date, step) {
24520 date.setFullYear(date.getFullYear() + step);
24521 }, function(start, end) {
24522 return end.getFullYear() - start.getFullYear();
24523 }, function(date) {
24524 return date.getFullYear();
24527 // An optimized implementation for this simple case.
24528 year.every = function(k) {
24529 return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
24530 date.setFullYear(Math.floor(date.getFullYear() / k) * k);
24531 date.setMonth(0, 1);
24532 date.setHours(0, 0, 0, 0);
24533 }, function(date, step) {
24534 date.setFullYear(date.getFullYear() + step * k);
24538 var years = year.range;
24540 var utcMinute = newInterval(function(date) {
24541 date.setUTCSeconds(0, 0);
24542 }, function(date, step) {
24543 date.setTime(+date + step * durationMinute);
24544 }, function(start, end) {
24545 return (end - start) / durationMinute;
24546 }, function(date) {
24547 return date.getUTCMinutes();
24550 var utcMinutes = utcMinute.range;
24552 var utcHour = newInterval(function(date) {
24553 date.setUTCMinutes(0, 0, 0);
24554 }, function(date, step) {
24555 date.setTime(+date + step * durationHour);
24556 }, function(start, end) {
24557 return (end - start) / durationHour;
24558 }, function(date) {
24559 return date.getUTCHours();
24562 var utcHours = utcHour.range;
24564 var utcDay = newInterval(function(date) {
24565 date.setUTCHours(0, 0, 0, 0);
24566 }, function(date, step) {
24567 date.setUTCDate(date.getUTCDate() + step);
24568 }, function(start, end) {
24569 return (end - start) / durationDay;
24570 }, function(date) {
24571 return date.getUTCDate() - 1;
24574 var utcDays = utcDay.range;
24576 function utcWeekday(i) {
24577 return newInterval(function(date) {
24578 date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);
24579 date.setUTCHours(0, 0, 0, 0);
24580 }, function(date, step) {
24581 date.setUTCDate(date.getUTCDate() + step * 7);
24582 }, function(start, end) {
24583 return (end - start) / durationWeek;
24587 var utcSunday = utcWeekday(0);
24588 var utcMonday = utcWeekday(1);
24589 var utcTuesday = utcWeekday(2);
24590 var utcWednesday = utcWeekday(3);
24591 var utcThursday = utcWeekday(4);
24592 var utcFriday = utcWeekday(5);
24593 var utcSaturday = utcWeekday(6);
24595 var utcSundays = utcSunday.range;
24596 var utcMondays = utcMonday.range;
24597 var utcTuesdays = utcTuesday.range;
24598 var utcWednesdays = utcWednesday.range;
24599 var utcThursdays = utcThursday.range;
24600 var utcFridays = utcFriday.range;
24601 var utcSaturdays = utcSaturday.range;
24603 var utcMonth = newInterval(function(date) {
24604 date.setUTCDate(1);
24605 date.setUTCHours(0, 0, 0, 0);
24606 }, function(date, step) {
24607 date.setUTCMonth(date.getUTCMonth() + step);
24608 }, function(start, end) {
24609 return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;
24610 }, function(date) {
24611 return date.getUTCMonth();
24614 var utcMonths = utcMonth.range;
24616 var utcYear = newInterval(function(date) {
24617 date.setUTCMonth(0, 1);
24618 date.setUTCHours(0, 0, 0, 0);
24619 }, function(date, step) {
24620 date.setUTCFullYear(date.getUTCFullYear() + step);
24621 }, function(start, end) {
24622 return end.getUTCFullYear() - start.getUTCFullYear();
24623 }, function(date) {
24624 return date.getUTCFullYear();
24627 // An optimized implementation for this simple case.
24628 utcYear.every = function(k) {
24629 return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
24630 date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);
24631 date.setUTCMonth(0, 1);
24632 date.setUTCHours(0, 0, 0, 0);
24633 }, function(date, step) {
24634 date.setUTCFullYear(date.getUTCFullYear() + step * k);
24638 var utcYears = utcYear.range;
24640 // Computes the decimal coefficient and exponent of the specified number x with
24641 // significant digits p, where x is positive and p is in [1, 21] or undefined.
24642 // For example, formatDecimal(1.23) returns ["123", 0].
24643 var formatDecimal = function(x, p) {
24644 if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity
24645 var i, coefficient = x.slice(0, i);
24647 // The string returned by toExponential either has the form \d\.\d+e[-+]\d+
24648 // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3).
24650 coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,
24655 var exponent$1 = function(x) {
24656 return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN;
24659 var formatGroup = function(grouping, thousands) {
24660 return function(value, width) {
24661 var i = value.length,
24667 while (i > 0 && g > 0) {
24668 if (length + g + 1 > width) g = Math.max(1, width - length);
24669 t.push(value.substring(i -= g, i + g));
24670 if ((length += g + 1) > width) break;
24671 g = grouping[j = (j + 1) % grouping.length];
24674 return t.reverse().join(thousands);
24678 var formatDefault = function(x, p) {
24679 x = x.toPrecision(p);
24681 out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) {
24683 case ".": i0 = i1 = i; break;
24684 case "0": if (i0 === 0) i0 = i; i1 = i; break;
24685 case "e": break out;
24686 default: if (i0 > 0) i0 = 0; break;
24690 return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x;
24693 var prefixExponent;
24695 var formatPrefixAuto = function(x, p) {
24696 var d = formatDecimal(x, p);
24697 if (!d) return x + "";
24698 var coefficient = d[0],
24700 i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,
24701 n = coefficient.length;
24702 return i === n ? coefficient
24703 : i > n ? coefficient + new Array(i - n + 1).join("0")
24704 : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i)
24705 : "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y!
24708 var formatRounded = function(x, p) {
24709 var d = formatDecimal(x, p);
24710 if (!d) return x + "";
24711 var coefficient = d[0],
24713 return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient
24714 : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1)
24715 : coefficient + new Array(exponent - coefficient.length + 2).join("0");
24718 var formatTypes = {
24720 "%": function(x, p) { return (x * 100).toFixed(p); },
24721 "b": function(x) { return Math.round(x).toString(2); },
24722 "c": function(x) { return x + ""; },
24723 "d": function(x) { return Math.round(x).toString(10); },
24724 "e": function(x, p) { return x.toExponential(p); },
24725 "f": function(x, p) { return x.toFixed(p); },
24726 "g": function(x, p) { return x.toPrecision(p); },
24727 "o": function(x) { return Math.round(x).toString(8); },
24728 "p": function(x, p) { return formatRounded(x * 100, p); },
24729 "r": formatRounded,
24730 "s": formatPrefixAuto,
24731 "X": function(x) { return Math.round(x).toString(16).toUpperCase(); },
24732 "x": function(x) { return Math.round(x).toString(16); }
24735 // [[fill]align][sign][symbol][0][width][,][.precision][type]
24736 var re = /^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i;
24738 var formatSpecifier = function(specifier) {
24739 return new FormatSpecifier(specifier);
24742 function FormatSpecifier(specifier) {
24743 if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier);
24746 fill = match[1] || " ",
24747 align = match[2] || ">",
24748 sign = match[3] || "-",
24749 symbol = match[4] || "",
24751 width = match[6] && +match[6],
24752 comma = !!match[7],
24753 precision = match[8] && +match[8].slice(1),
24754 type = match[9] || "";
24756 // The "n" type is an alias for ",g".
24757 if (type === "n") comma = true, type = "g";
24759 // Map invalid types to the default format.
24760 else if (!formatTypes[type]) type = "";
24762 // If zero fill is specified, padding goes after sign and before digits.
24763 if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "=";
24766 this.align = align;
24768 this.symbol = symbol;
24770 this.width = width;
24771 this.comma = comma;
24772 this.precision = precision;
24776 FormatSpecifier.prototype.toString = function() {
24781 + (this.zero ? "0" : "")
24782 + (this.width == null ? "" : Math.max(1, this.width | 0))
24783 + (this.comma ? "," : "")
24784 + (this.precision == null ? "" : "." + Math.max(0, this.precision | 0))
24788 var prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];
24790 function identity$3(x) {
24794 var formatLocale = function(locale) {
24795 var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity$3,
24796 currency = locale.currency,
24797 decimal = locale.decimal;
24799 function newFormat(specifier) {
24800 specifier = formatSpecifier(specifier);
24802 var fill = specifier.fill,
24803 align = specifier.align,
24804 sign = specifier.sign,
24805 symbol = specifier.symbol,
24806 zero = specifier.zero,
24807 width = specifier.width,
24808 comma = specifier.comma,
24809 precision = specifier.precision,
24810 type = specifier.type;
24812 // Compute the prefix and suffix.
24813 // For SI-prefix, the suffix is lazily computed.
24814 var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "",
24815 suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? "%" : "";
24817 // What format function should we use?
24818 // Is this an integer type?
24819 // Can this type generate exponential notation?
24820 var formatType = formatTypes[type],
24821 maybeSuffix = !type || /[defgprs%]/.test(type);
24823 // Set the default precision if not specified,
24824 // or clamp the specified precision to the supported range.
24825 // For significant precision, it must be in [1, 21].
24826 // For fixed precision, it must be in [0, 20].
24827 precision = precision == null ? (type ? 6 : 12)
24828 : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))
24829 : Math.max(0, Math.min(20, precision));
24831 function format(value) {
24832 var valuePrefix = prefix,
24833 valueSuffix = suffix,
24836 if (type === "c") {
24837 valueSuffix = formatType(value) + valueSuffix;
24842 // Convert negative to positive, and compute the prefix.
24843 // Note that -0 is not less than 0, but 1 / -0 is!
24844 var valueNegative = (value < 0 || 1 / value < 0) && (value *= -1, true);
24846 // Perform the initial formatting.
24847 value = formatType(value, precision);
24849 // If the original value was negative, it may be rounded to zero during
24850 // formatting; treat this as (positive) zero.
24851 if (valueNegative) {
24852 i = -1, n = value.length;
24853 valueNegative = false;
24855 if (c = value.charCodeAt(i), (48 < c && c < 58)
24856 || (type === "x" && 96 < c && c < 103)
24857 || (type === "X" && 64 < c && c < 71)) {
24858 valueNegative = true;
24864 // Compute the prefix and suffix.
24865 valuePrefix = (valueNegative ? (sign === "(" ? sign : "-") : sign === "-" || sign === "(" ? "" : sign) + valuePrefix;
24866 valueSuffix = valueSuffix + (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + (valueNegative && sign === "(" ? ")" : "");
24868 // Break the formatted value into the integer “value” part that can be
24869 // grouped, and fractional or exponential “suffix” part that is not.
24871 i = -1, n = value.length;
24873 if (c = value.charCodeAt(i), 48 > c || c > 57) {
24874 valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;
24875 value = value.slice(0, i);
24882 // If the fill character is not "0", grouping is applied before padding.
24883 if (comma && !zero) value = group(value, Infinity);
24885 // Compute the padding.
24886 var length = valuePrefix.length + value.length + valueSuffix.length,
24887 padding = length < width ? new Array(width - length + 1).join(fill) : "";
24889 // If the fill character is "0", grouping is applied after padding.
24890 if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = "";
24892 // Reconstruct the final output based on the desired alignment.
24894 case "<": return valuePrefix + value + valueSuffix + padding;
24895 case "=": return valuePrefix + padding + value + valueSuffix;
24896 case "^": return padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length);
24898 return padding + valuePrefix + value + valueSuffix;
24901 format.toString = function() {
24902 return specifier + "";
24908 function formatPrefix(specifier, value) {
24909 var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)),
24910 e = Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3,
24911 k = Math.pow(10, -e),
24912 prefix = prefixes[8 + e / 3];
24913 return function(value) {
24914 return f(k * value) + prefix;
24920 formatPrefix: formatPrefix
24932 currency: ["$", ""]
24935 function defaultLocale(definition) {
24936 locale$1 = formatLocale(definition);
24937 format = locale$1.format;
24938 formatPrefix = locale$1.formatPrefix;
24942 var precisionFixed = function(step) {
24943 return Math.max(0, -exponent$1(Math.abs(step)));
24946 var precisionPrefix = function(step, value) {
24947 return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3 - exponent$1(Math.abs(step)));
24950 var precisionRound = function(step, max) {
24951 step = Math.abs(step), max = Math.abs(max) - step;
24952 return Math.max(0, exponent$1(max) - exponent$1(step)) + 1;
24955 function localDate(d) {
24956 if (0 <= d.y && d.y < 100) {
24957 var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);
24958 date.setFullYear(d.y);
24961 return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);
24964 function utcDate(d) {
24965 if (0 <= d.y && d.y < 100) {
24966 var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));
24967 date.setUTCFullYear(d.y);
24970 return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));
24973 function newYear(y) {
24974 return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0};
24977 function formatLocale$1(locale) {
24978 var locale_dateTime = locale.dateTime,
24979 locale_date = locale.date,
24980 locale_time = locale.time,
24981 locale_periods = locale.periods,
24982 locale_weekdays = locale.days,
24983 locale_shortWeekdays = locale.shortDays,
24984 locale_months = locale.months,
24985 locale_shortMonths = locale.shortMonths;
24987 var periodRe = formatRe(locale_periods),
24988 periodLookup = formatLookup(locale_periods),
24989 weekdayRe = formatRe(locale_weekdays),
24990 weekdayLookup = formatLookup(locale_weekdays),
24991 shortWeekdayRe = formatRe(locale_shortWeekdays),
24992 shortWeekdayLookup = formatLookup(locale_shortWeekdays),
24993 monthRe = formatRe(locale_months),
24994 monthLookup = formatLookup(locale_months),
24995 shortMonthRe = formatRe(locale_shortMonths),
24996 shortMonthLookup = formatLookup(locale_shortMonths);
24999 "a": formatShortWeekday,
25000 "A": formatWeekday,
25001 "b": formatShortMonth,
25004 "d": formatDayOfMonth,
25005 "e": formatDayOfMonth,
25008 "j": formatDayOfYear,
25009 "L": formatMilliseconds,
25010 "m": formatMonthNumber,
25011 "M": formatMinutes,
25013 "S": formatSeconds,
25014 "U": formatWeekNumberSunday,
25015 "w": formatWeekdayNumber,
25016 "W": formatWeekNumberMonday,
25020 "Y": formatFullYear,
25022 "%": formatLiteralPercent
25026 "a": formatUTCShortWeekday,
25027 "A": formatUTCWeekday,
25028 "b": formatUTCShortMonth,
25029 "B": formatUTCMonth,
25031 "d": formatUTCDayOfMonth,
25032 "e": formatUTCDayOfMonth,
25033 "H": formatUTCHour24,
25034 "I": formatUTCHour12,
25035 "j": formatUTCDayOfYear,
25036 "L": formatUTCMilliseconds,
25037 "m": formatUTCMonthNumber,
25038 "M": formatUTCMinutes,
25039 "p": formatUTCPeriod,
25040 "S": formatUTCSeconds,
25041 "U": formatUTCWeekNumberSunday,
25042 "w": formatUTCWeekdayNumber,
25043 "W": formatUTCWeekNumberMonday,
25046 "y": formatUTCYear,
25047 "Y": formatUTCFullYear,
25048 "Z": formatUTCZone,
25049 "%": formatLiteralPercent
25053 "a": parseShortWeekday,
25055 "b": parseShortMonth,
25057 "c": parseLocaleDateTime,
25058 "d": parseDayOfMonth,
25059 "e": parseDayOfMonth,
25062 "j": parseDayOfYear,
25063 "L": parseMilliseconds,
25064 "m": parseMonthNumber,
25068 "U": parseWeekNumberSunday,
25069 "w": parseWeekdayNumber,
25070 "W": parseWeekNumberMonday,
25071 "x": parseLocaleDate,
25072 "X": parseLocaleTime,
25074 "Y": parseFullYear,
25076 "%": parseLiteralPercent
25079 // These recursive directive definitions must be deferred.
25080 formats.x = newFormat(locale_date, formats);
25081 formats.X = newFormat(locale_time, formats);
25082 formats.c = newFormat(locale_dateTime, formats);
25083 utcFormats.x = newFormat(locale_date, utcFormats);
25084 utcFormats.X = newFormat(locale_time, utcFormats);
25085 utcFormats.c = newFormat(locale_dateTime, utcFormats);
25087 function newFormat(specifier, formats) {
25088 return function(date) {
25092 n = specifier.length,
25097 if (!(date instanceof Date)) date = new Date(+date);
25100 if (specifier.charCodeAt(i) === 37) {
25101 string.push(specifier.slice(j, i));
25102 if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);
25103 else pad = c === "e" ? " " : "0";
25104 if (format = formats[c]) c = format(date, pad);
25110 string.push(specifier.slice(j, i));
25111 return string.join("");
25115 function newParse(specifier, newDate) {
25116 return function(string) {
25117 var d = newYear(1900),
25118 i = parseSpecifier(d, specifier, string += "", 0);
25119 if (i != string.length) return null;
25121 // The am-pm flag is 0 for AM, and 1 for PM.
25122 if ("p" in d) d.H = d.H % 12 + d.p * 12;
25124 // Convert day-of-week and week-of-year to day-of-year.
25125 if ("W" in d || "U" in d) {
25126 if (!("w" in d)) d.w = "W" in d ? 1 : 0;
25127 var day$$1 = "Z" in d ? utcDate(newYear(d.y)).getUTCDay() : newDate(newYear(d.y)).getDay();
25129 d.d = "W" in d ? (d.w + 6) % 7 + d.W * 7 - (day$$1 + 5) % 7 : d.w + d.U * 7 - (day$$1 + 6) % 7;
25132 // If a time zone is specified, all fields are interpreted as UTC and then
25133 // offset according to the specified time zone.
25135 d.H += d.Z / 100 | 0;
25140 // Otherwise, all fields are in local time.
25145 function parseSpecifier(d, specifier, string, j) {
25147 n = specifier.length,
25153 if (j >= m) return -1;
25154 c = specifier.charCodeAt(i++);
25156 c = specifier.charAt(i++);
25157 parse = parses[c in pads ? specifier.charAt(i++) : c];
25158 if (!parse || ((j = parse(d, string, j)) < 0)) return -1;
25159 } else if (c != string.charCodeAt(j++)) {
25167 function parsePeriod(d, string, i) {
25168 var n = periodRe.exec(string.slice(i));
25169 return n ? (d.p = periodLookup[n[0].toLowerCase()], i + n[0].length) : -1;
25172 function parseShortWeekday(d, string, i) {
25173 var n = shortWeekdayRe.exec(string.slice(i));
25174 return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;
25177 function parseWeekday(d, string, i) {
25178 var n = weekdayRe.exec(string.slice(i));
25179 return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;
25182 function parseShortMonth(d, string, i) {
25183 var n = shortMonthRe.exec(string.slice(i));
25184 return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1;
25187 function parseMonth(d, string, i) {
25188 var n = monthRe.exec(string.slice(i));
25189 return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1;
25192 function parseLocaleDateTime(d, string, i) {
25193 return parseSpecifier(d, locale_dateTime, string, i);
25196 function parseLocaleDate(d, string, i) {
25197 return parseSpecifier(d, locale_date, string, i);
25200 function parseLocaleTime(d, string, i) {
25201 return parseSpecifier(d, locale_time, string, i);
25204 function formatShortWeekday(d) {
25205 return locale_shortWeekdays[d.getDay()];
25208 function formatWeekday(d) {
25209 return locale_weekdays[d.getDay()];
25212 function formatShortMonth(d) {
25213 return locale_shortMonths[d.getMonth()];
25216 function formatMonth(d) {
25217 return locale_months[d.getMonth()];
25220 function formatPeriod(d) {
25221 return locale_periods[+(d.getHours() >= 12)];
25224 function formatUTCShortWeekday(d) {
25225 return locale_shortWeekdays[d.getUTCDay()];
25228 function formatUTCWeekday(d) {
25229 return locale_weekdays[d.getUTCDay()];
25232 function formatUTCShortMonth(d) {
25233 return locale_shortMonths[d.getUTCMonth()];
25236 function formatUTCMonth(d) {
25237 return locale_months[d.getUTCMonth()];
25240 function formatUTCPeriod(d) {
25241 return locale_periods[+(d.getUTCHours() >= 12)];
25245 format: function(specifier) {
25246 var f = newFormat(specifier += "", formats);
25247 f.toString = function() { return specifier; };
25250 parse: function(specifier) {
25251 var p = newParse(specifier += "", localDate);
25252 p.toString = function() { return specifier; };
25255 utcFormat: function(specifier) {
25256 var f = newFormat(specifier += "", utcFormats);
25257 f.toString = function() { return specifier; };
25260 utcParse: function(specifier) {
25261 var p = newParse(specifier, utcDate);
25262 p.toString = function() { return specifier; };
25268 var pads = {"-": "", "_": " ", "0": "0"};
25269 var numberRe = /^\s*\d+/;
25270 var percentRe = /^%/;
25271 var requoteRe = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
25273 function pad(value, fill, width) {
25274 var sign = value < 0 ? "-" : "",
25275 string = (sign ? -value : value) + "",
25276 length = string.length;
25277 return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);
25280 function requote(s) {
25281 return s.replace(requoteRe, "\\$&");
25284 function formatRe(names) {
25285 return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i");
25288 function formatLookup(names) {
25289 var map = {}, i = -1, n = names.length;
25290 while (++i < n) map[names[i].toLowerCase()] = i;
25294 function parseWeekdayNumber(d, string, i) {
25295 var n = numberRe.exec(string.slice(i, i + 1));
25296 return n ? (d.w = +n[0], i + n[0].length) : -1;
25299 function parseWeekNumberSunday(d, string, i) {
25300 var n = numberRe.exec(string.slice(i));
25301 return n ? (d.U = +n[0], i + n[0].length) : -1;
25304 function parseWeekNumberMonday(d, string, i) {
25305 var n = numberRe.exec(string.slice(i));
25306 return n ? (d.W = +n[0], i + n[0].length) : -1;
25309 function parseFullYear(d, string, i) {
25310 var n = numberRe.exec(string.slice(i, i + 4));
25311 return n ? (d.y = +n[0], i + n[0].length) : -1;
25314 function parseYear(d, string, i) {
25315 var n = numberRe.exec(string.slice(i, i + 2));
25316 return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;
25319 function parseZone(d, string, i) {
25320 var n = /^(Z)|([+-]\d\d)(?:\:?(\d\d))?/.exec(string.slice(i, i + 6));
25321 return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || "00")), i + n[0].length) : -1;
25324 function parseMonthNumber(d, string, i) {
25325 var n = numberRe.exec(string.slice(i, i + 2));
25326 return n ? (d.m = n[0] - 1, i + n[0].length) : -1;
25329 function parseDayOfMonth(d, string, i) {
25330 var n = numberRe.exec(string.slice(i, i + 2));
25331 return n ? (d.d = +n[0], i + n[0].length) : -1;
25334 function parseDayOfYear(d, string, i) {
25335 var n = numberRe.exec(string.slice(i, i + 3));
25336 return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;
25339 function parseHour24(d, string, i) {
25340 var n = numberRe.exec(string.slice(i, i + 2));
25341 return n ? (d.H = +n[0], i + n[0].length) : -1;
25344 function parseMinutes(d, string, i) {
25345 var n = numberRe.exec(string.slice(i, i + 2));
25346 return n ? (d.M = +n[0], i + n[0].length) : -1;
25349 function parseSeconds(d, string, i) {
25350 var n = numberRe.exec(string.slice(i, i + 2));
25351 return n ? (d.S = +n[0], i + n[0].length) : -1;
25354 function parseMilliseconds(d, string, i) {
25355 var n = numberRe.exec(string.slice(i, i + 3));
25356 return n ? (d.L = +n[0], i + n[0].length) : -1;
25359 function parseLiteralPercent(d, string, i) {
25360 var n = percentRe.exec(string.slice(i, i + 1));
25361 return n ? i + n[0].length : -1;
25364 function formatDayOfMonth(d, p) {
25365 return pad(d.getDate(), p, 2);
25368 function formatHour24(d, p) {
25369 return pad(d.getHours(), p, 2);
25372 function formatHour12(d, p) {
25373 return pad(d.getHours() % 12 || 12, p, 2);
25376 function formatDayOfYear(d, p) {
25377 return pad(1 + day.count(year(d), d), p, 3);
25380 function formatMilliseconds(d, p) {
25381 return pad(d.getMilliseconds(), p, 3);
25384 function formatMonthNumber(d, p) {
25385 return pad(d.getMonth() + 1, p, 2);
25388 function formatMinutes(d, p) {
25389 return pad(d.getMinutes(), p, 2);
25392 function formatSeconds(d, p) {
25393 return pad(d.getSeconds(), p, 2);
25396 function formatWeekNumberSunday(d, p) {
25397 return pad(sunday.count(year(d), d), p, 2);
25400 function formatWeekdayNumber(d) {
25404 function formatWeekNumberMonday(d, p) {
25405 return pad(monday.count(year(d), d), p, 2);
25408 function formatYear(d, p) {
25409 return pad(d.getFullYear() % 100, p, 2);
25412 function formatFullYear(d, p) {
25413 return pad(d.getFullYear() % 10000, p, 4);
25416 function formatZone(d) {
25417 var z = d.getTimezoneOffset();
25418 return (z > 0 ? "-" : (z *= -1, "+"))
25419 + pad(z / 60 | 0, "0", 2)
25420 + pad(z % 60, "0", 2);
25423 function formatUTCDayOfMonth(d, p) {
25424 return pad(d.getUTCDate(), p, 2);
25427 function formatUTCHour24(d, p) {
25428 return pad(d.getUTCHours(), p, 2);
25431 function formatUTCHour12(d, p) {
25432 return pad(d.getUTCHours() % 12 || 12, p, 2);
25435 function formatUTCDayOfYear(d, p) {
25436 return pad(1 + utcDay.count(utcYear(d), d), p, 3);
25439 function formatUTCMilliseconds(d, p) {
25440 return pad(d.getUTCMilliseconds(), p, 3);
25443 function formatUTCMonthNumber(d, p) {
25444 return pad(d.getUTCMonth() + 1, p, 2);
25447 function formatUTCMinutes(d, p) {
25448 return pad(d.getUTCMinutes(), p, 2);
25451 function formatUTCSeconds(d, p) {
25452 return pad(d.getUTCSeconds(), p, 2);
25455 function formatUTCWeekNumberSunday(d, p) {
25456 return pad(utcSunday.count(utcYear(d), d), p, 2);
25459 function formatUTCWeekdayNumber(d) {
25460 return d.getUTCDay();
25463 function formatUTCWeekNumberMonday(d, p) {
25464 return pad(utcMonday.count(utcYear(d), d), p, 2);
25467 function formatUTCYear(d, p) {
25468 return pad(d.getUTCFullYear() % 100, p, 2);
25471 function formatUTCFullYear(d, p) {
25472 return pad(d.getUTCFullYear() % 10000, p, 4);
25475 function formatUTCZone() {
25479 function formatLiteralPercent() {
25490 dateTime: "%x, %X",
25491 date: "%-m/%-d/%Y",
25492 time: "%-I:%M:%S %p",
25493 periods: ["AM", "PM"],
25494 days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
25495 shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
25496 months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
25497 shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
25500 function defaultLocale$1(definition) {
25501 locale$2 = formatLocale$1(definition);
25502 timeFormat = locale$2.format;
25503 timeParse = locale$2.parse;
25504 utcFormat = locale$2.utcFormat;
25505 utcParse = locale$2.utcParse;
25509 var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ";
25511 function formatIsoNative(date) {
25512 return date.toISOString();
25515 var formatIso = Date.prototype.toISOString
25517 : utcFormat(isoSpecifier);
25519 function parseIsoNative(string) {
25520 var date = new Date(string);
25521 return isNaN(date) ? null : date;
25524 var parseIso = +new Date("2000-01-01T00:00:00.000Z")
25526 : utcParse(isoSpecifier);
25528 var array$2 = Array.prototype;
25530 var map$3 = array$2.map;
25531 var slice$3 = array$2.slice;
25533 var implicit = {name: "implicit"};
25535 function ordinal(range) {
25536 var index = map$1(),
25538 unknown = implicit;
25540 range = range == null ? [] : slice$3.call(range);
25542 function scale(d) {
25543 var key = d + "", i = index.get(key);
25545 if (unknown !== implicit) return unknown;
25546 index.set(key, i = domain.push(d));
25548 return range[(i - 1) % range.length];
25551 scale.domain = function(_) {
25552 if (!arguments.length) return domain.slice();
25553 domain = [], index = map$1();
25554 var i = -1, n = _.length, d, key;
25555 while (++i < n) if (!index.has(key = (d = _[i]) + "")) index.set(key, domain.push(d));
25559 scale.range = function(_) {
25560 return arguments.length ? (range = slice$3.call(_), scale) : range.slice();
25563 scale.unknown = function(_) {
25564 return arguments.length ? (unknown = _, scale) : unknown;
25567 scale.copy = function() {
25578 var scale = ordinal().unknown(undefined),
25579 domain = scale.domain,
25580 ordinalRange = scale.range,
25589 delete scale.unknown;
25591 function rescale() {
25592 var n = domain().length,
25593 reverse = range$$1[1] < range$$1[0],
25594 start = range$$1[reverse - 0],
25595 stop = range$$1[1 - reverse];
25596 step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2);
25597 if (round) step = Math.floor(step);
25598 start += (stop - start - step * (n - paddingInner)) * align;
25599 bandwidth = step * (1 - paddingInner);
25600 if (round) start = Math.round(start), bandwidth = Math.round(bandwidth);
25601 var values = range(n).map(function(i) { return start + step * i; });
25602 return ordinalRange(reverse ? values.reverse() : values);
25605 scale.domain = function(_) {
25606 return arguments.length ? (domain(_), rescale()) : domain();
25609 scale.range = function(_) {
25610 return arguments.length ? (range$$1 = [+_[0], +_[1]], rescale()) : range$$1.slice();
25613 scale.rangeRound = function(_) {
25614 return range$$1 = [+_[0], +_[1]], round = true, rescale();
25617 scale.bandwidth = function() {
25621 scale.step = function() {
25625 scale.round = function(_) {
25626 return arguments.length ? (round = !!_, rescale()) : round;
25629 scale.padding = function(_) {
25630 return arguments.length ? (paddingInner = paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
25633 scale.paddingInner = function(_) {
25634 return arguments.length ? (paddingInner = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
25637 scale.paddingOuter = function(_) {
25638 return arguments.length ? (paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingOuter;
25641 scale.align = function(_) {
25642 return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align;
25645 scale.copy = function() {
25650 .paddingInner(paddingInner)
25651 .paddingOuter(paddingOuter)
25658 function pointish(scale) {
25659 var copy = scale.copy;
25661 scale.padding = scale.paddingOuter;
25662 delete scale.paddingInner;
25663 delete scale.paddingOuter;
25665 scale.copy = function() {
25666 return pointish(copy());
25672 function point$4() {
25673 return pointish(band().paddingInner(1));
25676 var constant$4 = function(x) {
25677 return function() {
25682 var number$1 = function(x) {
25688 function deinterpolateLinear(a, b) {
25689 return (b -= (a = +a))
25690 ? function(x) { return (x - a) / b; }
25694 function deinterpolateClamp(deinterpolate) {
25695 return function(a, b) {
25696 var d = deinterpolate(a = +a, b = +b);
25697 return function(x) { return x <= a ? 0 : x >= b ? 1 : d(x); };
25701 function reinterpolateClamp(reinterpolate) {
25702 return function(a, b) {
25703 var r = reinterpolate(a = +a, b = +b);
25704 return function(t) { return t <= 0 ? a : t >= 1 ? b : r(t); };
25708 function bimap(domain, range$$1, deinterpolate, reinterpolate) {
25709 var d0 = domain[0], d1 = domain[1], r0 = range$$1[0], r1 = range$$1[1];
25710 if (d1 < d0) d0 = deinterpolate(d1, d0), r0 = reinterpolate(r1, r0);
25711 else d0 = deinterpolate(d0, d1), r0 = reinterpolate(r0, r1);
25712 return function(x) { return r0(d0(x)); };
25715 function polymap(domain, range$$1, deinterpolate, reinterpolate) {
25716 var j = Math.min(domain.length, range$$1.length) - 1,
25721 // Reverse descending domains.
25722 if (domain[j] < domain[0]) {
25723 domain = domain.slice().reverse();
25724 range$$1 = range$$1.slice().reverse();
25728 d[i] = deinterpolate(domain[i], domain[i + 1]);
25729 r[i] = reinterpolate(range$$1[i], range$$1[i + 1]);
25732 return function(x) {
25733 var i = bisectRight(domain, x, 1, j) - 1;
25734 return r[i](d[i](x));
25738 function copy(source, target) {
25740 .domain(source.domain())
25741 .range(source.range())
25742 .interpolate(source.interpolate())
25743 .clamp(source.clamp());
25746 // deinterpolate(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].
25747 // reinterpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding domain value x in [a,b].
25748 function continuous(deinterpolate, reinterpolate) {
25751 interpolate$$1 = interpolate,
25757 function rescale() {
25758 piecewise = Math.min(domain.length, range$$1.length) > 2 ? polymap : bimap;
25759 output = input = null;
25763 function scale(x) {
25764 return (output || (output = piecewise(domain, range$$1, clamp ? deinterpolateClamp(deinterpolate) : deinterpolate, interpolate$$1)))(+x);
25767 scale.invert = function(y) {
25768 return (input || (input = piecewise(range$$1, domain, deinterpolateLinear, clamp ? reinterpolateClamp(reinterpolate) : reinterpolate)))(+y);
25771 scale.domain = function(_) {
25772 return arguments.length ? (domain = map$3.call(_, number$1), rescale()) : domain.slice();
25775 scale.range = function(_) {
25776 return arguments.length ? (range$$1 = slice$3.call(_), rescale()) : range$$1.slice();
25779 scale.rangeRound = function(_) {
25780 return range$$1 = slice$3.call(_), interpolate$$1 = interpolateRound, rescale();
25783 scale.clamp = function(_) {
25784 return arguments.length ? (clamp = !!_, rescale()) : clamp;
25787 scale.interpolate = function(_) {
25788 return arguments.length ? (interpolate$$1 = _, rescale()) : interpolate$$1;
25794 var tickFormat = function(domain, count, specifier) {
25795 var start = domain[0],
25796 stop = domain[domain.length - 1],
25797 step = tickStep(start, stop, count == null ? 10 : count),
25799 specifier = formatSpecifier(specifier == null ? ",f" : specifier);
25800 switch (specifier.type) {
25802 var value = Math.max(Math.abs(start), Math.abs(stop));
25803 if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;
25804 return formatPrefix(specifier, value);
25811 if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e");
25816 if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2;
25820 return format(specifier);
25823 function linearish(scale) {
25824 var domain = scale.domain;
25826 scale.ticks = function(count) {
25828 return ticks(d[0], d[d.length - 1], count == null ? 10 : count);
25831 scale.tickFormat = function(count, specifier) {
25832 return tickFormat(domain(), count, specifier);
25835 scale.nice = function(count) {
25838 n = count == null ? 10 : count,
25841 step = tickStep(start, stop, n);
25844 step = tickStep(Math.floor(start / step) * step, Math.ceil(stop / step) * step, n);
25845 d[0] = Math.floor(start / step) * step;
25846 d[i] = Math.ceil(stop / step) * step;
25856 function linear$2() {
25857 var scale = continuous(deinterpolateLinear, interpolateNumber);
25859 scale.copy = function() {
25860 return copy(scale, linear$2());
25863 return linearish(scale);
25866 function identity$4() {
25867 var domain = [0, 1];
25869 function scale(x) {
25873 scale.invert = scale;
25875 scale.domain = scale.range = function(_) {
25876 return arguments.length ? (domain = map$3.call(_, number$1), scale) : domain.slice();
25879 scale.copy = function() {
25880 return identity$4().domain(domain);
25883 return linearish(scale);
25886 var nice = function(domain, interval) {
25887 domain = domain.slice();
25890 i1 = domain.length - 1,
25896 t = i0, i0 = i1, i1 = t;
25897 t = x0, x0 = x1, x1 = t;
25900 domain[i0] = interval.floor(x0);
25901 domain[i1] = interval.ceil(x1);
25905 function deinterpolate(a, b) {
25906 return (b = Math.log(b / a))
25907 ? function(x) { return Math.log(x / a) / b; }
25911 function reinterpolate(a, b) {
25913 ? function(t) { return -Math.pow(-b, t) * Math.pow(-a, 1 - t); }
25914 : function(t) { return Math.pow(b, t) * Math.pow(a, 1 - t); };
25917 function pow10(x) {
25918 return isFinite(x) ? +("1e" + x) : x < 0 ? 0 : x;
25921 function powp(base) {
25922 return base === 10 ? pow10
25923 : base === Math.E ? Math.exp
25924 : function(x) { return Math.pow(base, x); };
25927 function logp(base) {
25928 return base === Math.E ? Math.log
25929 : base === 10 && Math.log10
25930 || base === 2 && Math.log2
25931 || (base = Math.log(base), function(x) { return Math.log(x) / base; });
25934 function reflect(f) {
25935 return function(x) {
25941 var scale = continuous(deinterpolate, reinterpolate).domain([1, 10]),
25942 domain = scale.domain,
25947 function rescale() {
25948 logs = logp(base), pows = powp(base);
25949 if (domain()[0] < 0) logs = reflect(logs), pows = reflect(pows);
25953 scale.base = function(_) {
25954 return arguments.length ? (base = +_, rescale()) : base;
25957 scale.domain = function(_) {
25958 return arguments.length ? (domain(_), rescale()) : domain();
25961 scale.ticks = function(count) {
25964 v = d[d.length - 1],
25967 if (r = v < u) i = u, u = v, v = i;
25974 n = count == null ? 10 : +count,
25977 if (!(base % 1) && j - i < n) {
25978 i = Math.round(i) - 1, j = Math.round(j) + 1;
25979 if (u > 0) for (; i < j; ++i) {
25980 for (k = 1, p = pows(i); k < base; ++k) {
25982 if (t < u) continue;
25986 } else for (; i < j; ++i) {
25987 for (k = base - 1, p = pows(i); k >= 1; --k) {
25989 if (t < u) continue;
25995 z = ticks(i, j, Math.min(j - i, n)).map(pows);
25998 return r ? z.reverse() : z;
26001 scale.tickFormat = function(count, specifier) {
26002 if (specifier == null) specifier = base === 10 ? ".0e" : ",";
26003 if (typeof specifier !== "function") specifier = format(specifier);
26004 if (count === Infinity) return specifier;
26005 if (count == null) count = 10;
26006 var k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?
26007 return function(d) {
26008 var i = d / pows(Math.round(logs(d)));
26009 if (i * base < base - 0.5) i *= base;
26010 return i <= k ? specifier(d) : "";
26014 scale.nice = function() {
26015 return domain(nice(domain(), {
26016 floor: function(x) { return pows(Math.floor(logs(x))); },
26017 ceil: function(x) { return pows(Math.ceil(logs(x))); }
26021 scale.copy = function() {
26022 return copy(scale, log().base(base));
26028 function raise(x, exponent) {
26029 return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent);
26034 scale = continuous(deinterpolate, reinterpolate),
26035 domain = scale.domain;
26037 function deinterpolate(a, b) {
26038 return (b = raise(b, exponent) - (a = raise(a, exponent)))
26039 ? function(x) { return (raise(x, exponent) - a) / b; }
26043 function reinterpolate(a, b) {
26044 b = raise(b, exponent) - (a = raise(a, exponent));
26045 return function(t) { return raise(a + b * t, 1 / exponent); };
26048 scale.exponent = function(_) {
26049 return arguments.length ? (exponent = +_, domain(domain())) : exponent;
26052 scale.copy = function() {
26053 return copy(scale, pow().exponent(exponent));
26056 return linearish(scale);
26060 return pow().exponent(0.5);
26063 function quantile$$1() {
26068 function rescale() {
26069 var i = 0, n = Math.max(1, range$$1.length);
26070 thresholds = new Array(n - 1);
26071 while (++i < n) thresholds[i - 1] = threshold(domain, i / n);
26075 function scale(x) {
26076 if (!isNaN(x = +x)) return range$$1[bisectRight(thresholds, x)];
26079 scale.invertExtent = function(y) {
26080 var i = range$$1.indexOf(y);
26081 return i < 0 ? [NaN, NaN] : [
26082 i > 0 ? thresholds[i - 1] : domain[0],
26083 i < thresholds.length ? thresholds[i] : domain[domain.length - 1]
26087 scale.domain = function(_) {
26088 if (!arguments.length) return domain.slice();
26090 for (var i = 0, n = _.length, d; i < n; ++i) if (d = _[i], d != null && !isNaN(d = +d)) domain.push(d);
26091 domain.sort(ascending);
26095 scale.range = function(_) {
26096 return arguments.length ? (range$$1 = slice$3.call(_), rescale()) : range$$1.slice();
26099 scale.quantiles = function() {
26100 return thresholds.slice();
26103 scale.copy = function() {
26104 return quantile$$1()
26112 function quantize$1() {
26119 function scale(x) {
26120 if (x <= x) return range$$1[bisectRight(domain, x, 0, n)];
26123 function rescale() {
26125 domain = new Array(n);
26126 while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1);
26130 scale.domain = function(_) {
26131 return arguments.length ? (x0 = +_[0], x1 = +_[1], rescale()) : [x0, x1];
26134 scale.range = function(_) {
26135 return arguments.length ? (n = (range$$1 = slice$3.call(_)).length - 1, rescale()) : range$$1.slice();
26138 scale.invertExtent = function(y) {
26139 var i = range$$1.indexOf(y);
26140 return i < 0 ? [NaN, NaN]
26141 : i < 1 ? [x0, domain[0]]
26142 : i >= n ? [domain[n - 1], x1]
26143 : [domain[i - 1], domain[i]];
26146 scale.copy = function() {
26147 return quantize$1()
26152 return linearish(scale);
26155 function threshold$1() {
26156 var domain = [0.5],
26160 function scale(x) {
26161 if (x <= x) return range$$1[bisectRight(domain, x, 0, n)];
26164 scale.domain = function(_) {
26165 return arguments.length ? (domain = slice$3.call(_), n = Math.min(domain.length, range$$1.length - 1), scale) : domain.slice();
26168 scale.range = function(_) {
26169 return arguments.length ? (range$$1 = slice$3.call(_), n = Math.min(domain.length, range$$1.length - 1), scale) : range$$1.slice();
26172 scale.invertExtent = function(y) {
26173 var i = range$$1.indexOf(y);
26174 return [domain[i - 1], domain[i]];
26177 scale.copy = function() {
26178 return threshold$1()
26186 var durationSecond$1 = 1000;
26187 var durationMinute$1 = durationSecond$1 * 60;
26188 var durationHour$1 = durationMinute$1 * 60;
26189 var durationDay$1 = durationHour$1 * 24;
26190 var durationWeek$1 = durationDay$1 * 7;
26191 var durationMonth = durationDay$1 * 30;
26192 var durationYear = durationDay$1 * 365;
26194 function date$1(t) {
26195 return new Date(t);
26198 function number$2(t) {
26199 return t instanceof Date ? +t : +new Date(+t);
26202 function calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format) {
26203 var scale = continuous(deinterpolateLinear, interpolateNumber),
26204 invert = scale.invert,
26205 domain = scale.domain;
26207 var formatMillisecond = format(".%L"),
26208 formatSecond = format(":%S"),
26209 formatMinute = format("%I:%M"),
26210 formatHour = format("%I %p"),
26211 formatDay = format("%a %d"),
26212 formatWeek = format("%b %d"),
26213 formatMonth = format("%B"),
26214 formatYear = format("%Y");
26216 var tickIntervals = [
26217 [second$$1, 1, durationSecond$1],
26218 [second$$1, 5, 5 * durationSecond$1],
26219 [second$$1, 15, 15 * durationSecond$1],
26220 [second$$1, 30, 30 * durationSecond$1],
26221 [minute$$1, 1, durationMinute$1],
26222 [minute$$1, 5, 5 * durationMinute$1],
26223 [minute$$1, 15, 15 * durationMinute$1],
26224 [minute$$1, 30, 30 * durationMinute$1],
26225 [ hour$$1, 1, durationHour$1 ],
26226 [ hour$$1, 3, 3 * durationHour$1 ],
26227 [ hour$$1, 6, 6 * durationHour$1 ],
26228 [ hour$$1, 12, 12 * durationHour$1 ],
26229 [ day$$1, 1, durationDay$1 ],
26230 [ day$$1, 2, 2 * durationDay$1 ],
26231 [ week, 1, durationWeek$1 ],
26232 [ month$$1, 1, durationMonth ],
26233 [ month$$1, 3, 3 * durationMonth ],
26234 [ year$$1, 1, durationYear ]
26237 function tickFormat(date) {
26238 return (second$$1(date) < date ? formatMillisecond
26239 : minute$$1(date) < date ? formatSecond
26240 : hour$$1(date) < date ? formatMinute
26241 : day$$1(date) < date ? formatHour
26242 : month$$1(date) < date ? (week(date) < date ? formatDay : formatWeek)
26243 : year$$1(date) < date ? formatMonth
26244 : formatYear)(date);
26247 function tickInterval(interval, start, stop, step) {
26248 if (interval == null) interval = 10;
26250 // If a desired tick count is specified, pick a reasonable tick interval
26251 // based on the extent of the domain and a rough estimate of tick size.
26252 // Otherwise, assume interval is already a time interval and use it.
26253 if (typeof interval === "number") {
26254 var target = Math.abs(stop - start) / interval,
26255 i = bisector(function(i) { return i[2]; }).right(tickIntervals, target);
26256 if (i === tickIntervals.length) {
26257 step = tickStep(start / durationYear, stop / durationYear, interval);
26258 interval = year$$1;
26260 i = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i];
26264 step = tickStep(start, stop, interval);
26265 interval = millisecond$$1;
26269 return step == null ? interval : interval.every(step);
26272 scale.invert = function(y) {
26273 return new Date(invert(y));
26276 scale.domain = function(_) {
26277 return arguments.length ? domain(map$3.call(_, number$2)) : domain().map(date$1);
26280 scale.ticks = function(interval, step) {
26283 t1 = d[d.length - 1],
26286 if (r) t = t0, t0 = t1, t1 = t;
26287 t = tickInterval(interval, t0, t1, step);
26288 t = t ? t.range(t0, t1 + 1) : []; // inclusive stop
26289 return r ? t.reverse() : t;
26292 scale.tickFormat = function(count, specifier) {
26293 return specifier == null ? tickFormat : format(specifier);
26296 scale.nice = function(interval, step) {
26298 return (interval = tickInterval(interval, d[0], d[d.length - 1], step))
26299 ? domain(nice(d, interval))
26303 scale.copy = function() {
26304 return copy(scale, calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format));
26310 var time = function() {
26311 return calendar(year, month, sunday, day, hour, minute, second, millisecond, timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]);
26314 var utcTime = function() {
26315 return calendar(utcYear, utcMonth, utcSunday, utcDay, utcHour, utcMinute, second, millisecond, utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]);
26318 var colors = function(s) {
26319 return s.match(/.{6}/g).map(function(x) {
26324 var category10 = colors("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf");
26326 var category20b = colors("393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6");
26328 var category20c = colors("3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9");
26330 var category20 = colors("1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5");
26332 var cubehelix$3 = cubehelixLong(cubehelix(300, 0.5, 0.0), cubehelix(-240, 0.5, 1.0));
26334 var warm = cubehelixLong(cubehelix(-100, 0.75, 0.35), cubehelix(80, 1.50, 0.8));
26336 var cool = cubehelixLong(cubehelix(260, 0.75, 0.35), cubehelix(80, 1.50, 0.8));
26338 var rainbow = cubehelix();
26340 var rainbow$1 = function(t) {
26341 if (t < 0 || t > 1) t -= Math.floor(t);
26342 var ts = Math.abs(t - 0.5);
26343 rainbow.h = 360 * t - 100;
26344 rainbow.s = 1.5 - 1.5 * ts;
26345 rainbow.l = 0.8 - 0.9 * ts;
26346 return rainbow + "";
26349 function ramp(range) {
26350 var n = range.length;
26351 return function(t) {
26352 return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];
26356 var viridis = ramp(colors("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));
26358 var magma = ramp(colors("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf"));
26360 var inferno = ramp(colors("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4"));
26362 var plasma = ramp(colors("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921"));
26364 function sequential(interpolator) {
26369 function scale(x) {
26370 var t = (x - x0) / (x1 - x0);
26371 return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t);
26374 scale.domain = function(_) {
26375 return arguments.length ? (x0 = +_[0], x1 = +_[1], scale) : [x0, x1];
26378 scale.clamp = function(_) {
26379 return arguments.length ? (clamp = !!_, scale) : clamp;
26382 scale.interpolator = function(_) {
26383 return arguments.length ? (interpolator = _, scale) : interpolator;
26386 scale.copy = function() {
26387 return sequential(interpolator).domain([x0, x1]).clamp(clamp);
26390 return linearish(scale);
26393 var xhtml = "http://www.w3.org/1999/xhtml";
26396 svg: "http://www.w3.org/2000/svg",
26398 xlink: "http://www.w3.org/1999/xlink",
26399 xml: "http://www.w3.org/XML/1998/namespace",
26400 xmlns: "http://www.w3.org/2000/xmlns/"
26403 var namespace = function(name) {
26404 var prefix = name += "", i = prefix.indexOf(":");
26405 if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1);
26406 return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name;
26409 function creatorInherit(name) {
26410 return function() {
26411 var document = this.ownerDocument,
26412 uri = this.namespaceURI;
26413 return uri === xhtml && document.documentElement.namespaceURI === xhtml
26414 ? document.createElement(name)
26415 : document.createElementNS(uri, name);
26419 function creatorFixed(fullname) {
26420 return function() {
26421 return this.ownerDocument.createElementNS(fullname.space, fullname.local);
26425 var creator = function(name) {
26426 var fullname = namespace(name);
26427 return (fullname.local
26429 : creatorInherit)(fullname);
26439 this._ = "@" + (++nextId).toString(36);
26442 Local.prototype = local.prototype = {
26443 constructor: Local,
26444 get: function(node) {
26446 while (!(id in node)) if (!(node = node.parentNode)) return;
26449 set: function(node, value) {
26450 return node[this._] = value;
26452 remove: function(node) {
26453 return this._ in node && delete node[this._];
26455 toString: function() {
26460 var matcher = function(selector) {
26461 return function() {
26462 return this.matches(selector);
26466 if (typeof document !== "undefined") {
26467 var element = document.documentElement;
26468 if (!element.matches) {
26469 var vendorMatches = element.webkitMatchesSelector
26470 || element.msMatchesSelector
26471 || element.mozMatchesSelector
26472 || element.oMatchesSelector;
26473 matcher = function(selector) {
26474 return function() {
26475 return vendorMatches.call(this, selector);
26481 var matcher$1 = matcher;
26483 var filterEvents = {};
26487 if (typeof document !== "undefined") {
26488 var element$1 = document.documentElement;
26489 if (!("onmouseenter" in element$1)) {
26490 filterEvents = {mouseenter: "mouseover", mouseleave: "mouseout"};
26494 function filterContextListener(listener, index, group) {
26495 listener = contextListener(listener, index, group);
26496 return function(event) {
26497 var related = event.relatedTarget;
26498 if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) {
26499 listener.call(this, event);
26504 function contextListener(listener, index, group) {
26505 return function(event1) {
26506 var event0 = event; // Events can be reentrant (e.g., focus).
26509 listener.call(this, this.__data__, index, group);
26516 function parseTypenames$1(typenames) {
26517 return typenames.trim().split(/^|\s+/).map(function(t) {
26518 var name = "", i = t.indexOf(".");
26519 if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
26520 return {type: t, name: name};
26524 function onRemove(typename) {
26525 return function() {
26526 var on = this.__on;
26528 for (var j = 0, i = -1, m = on.length, o; j < m; ++j) {
26529 if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) {
26530 this.removeEventListener(o.type, o.listener, o.capture);
26535 if (++i) on.length = i;
26536 else delete this.__on;
26540 function onAdd(typename, value, capture) {
26541 var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener;
26542 return function(d, i, group) {
26543 var on = this.__on, o, listener = wrap(value, i, group);
26544 if (on) for (var j = 0, m = on.length; j < m; ++j) {
26545 if ((o = on[j]).type === typename.type && o.name === typename.name) {
26546 this.removeEventListener(o.type, o.listener, o.capture);
26547 this.addEventListener(o.type, o.listener = listener, o.capture = capture);
26552 this.addEventListener(typename.type, listener, capture);
26553 o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture};
26554 if (!on) this.__on = [o];
26559 var selection_on = function(typename, value, capture) {
26560 var typenames = parseTypenames$1(typename + ""), i, n = typenames.length, t;
26562 if (arguments.length < 2) {
26563 var on = this.node().__on;
26564 if (on) for (var j = 0, m = on.length, o; j < m; ++j) {
26565 for (i = 0, o = on[j]; i < n; ++i) {
26566 if ((t = typenames[i]).type === o.type && t.name === o.name) {
26574 on = value ? onAdd : onRemove;
26575 if (capture == null) capture = false;
26576 for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture));
26580 function customEvent(event1, listener, that, args) {
26581 var event0 = event;
26582 event1.sourceEvent = event;
26585 return listener.apply(that, args);
26591 var sourceEvent = function() {
26592 var current = event, source;
26593 while (source = current.sourceEvent) current = source;
26597 var point$5 = function(node, event) {
26598 var svg = node.ownerSVGElement || node;
26600 if (svg.createSVGPoint) {
26601 var point = svg.createSVGPoint();
26602 point.x = event.clientX, point.y = event.clientY;
26603 point = point.matrixTransform(node.getScreenCTM().inverse());
26604 return [point.x, point.y];
26607 var rect = node.getBoundingClientRect();
26608 return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];
26611 var mouse = function(node) {
26612 var event = sourceEvent();
26613 if (event.changedTouches) event = event.changedTouches[0];
26614 return point$5(node, event);
26617 function none$2() {}
26619 var selector = function(selector) {
26620 return selector == null ? none$2 : function() {
26621 return this.querySelector(selector);
26625 var selection_select = function(select) {
26626 if (typeof select !== "function") select = selector(select);
26628 for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
26629 for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
26630 if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {
26631 if ("__data__" in node) subnode.__data__ = node.__data__;
26632 subgroup[i] = subnode;
26637 return new Selection(subgroups, this._parents);
26644 var selectorAll = function(selector) {
26645 return selector == null ? empty : function() {
26646 return this.querySelectorAll(selector);
26650 var selection_selectAll = function(select) {
26651 if (typeof select !== "function") select = selectorAll(select);
26653 for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
26654 for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
26655 if (node = group[i]) {
26656 subgroups.push(select.call(node, node.__data__, i, group));
26657 parents.push(node);
26662 return new Selection(subgroups, parents);
26665 var selection_filter = function(match) {
26666 if (typeof match !== "function") match = matcher$1(match);
26668 for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
26669 for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
26670 if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
26671 subgroup.push(node);
26676 return new Selection(subgroups, this._parents);
26679 var sparse = function(update) {
26680 return new Array(update.length);
26683 var selection_enter = function() {
26684 return new Selection(this._enter || this._groups.map(sparse), this._parents);
26687 function EnterNode(parent, datum) {
26688 this.ownerDocument = parent.ownerDocument;
26689 this.namespaceURI = parent.namespaceURI;
26691 this._parent = parent;
26692 this.__data__ = datum;
26695 EnterNode.prototype = {
26696 constructor: EnterNode,
26697 appendChild: function(child) { return this._parent.insertBefore(child, this._next); },
26698 insertBefore: function(child, next) { return this._parent.insertBefore(child, next); },
26699 querySelector: function(selector) { return this._parent.querySelector(selector); },
26700 querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); }
26703 var constant$5 = function(x) {
26704 return function() {
26709 var keyPrefix = "$"; // Protect against keys like “__proto__”.
26711 function bindIndex(parent, group, enter, update, exit, data) {
26714 groupLength = group.length,
26715 dataLength = data.length;
26717 // Put any non-null nodes that fit into update.
26718 // Put any null nodes into enter.
26719 // Put any remaining data into enter.
26720 for (; i < dataLength; ++i) {
26721 if (node = group[i]) {
26722 node.__data__ = data[i];
26725 enter[i] = new EnterNode(parent, data[i]);
26729 // Put any non-null nodes that don’t fit into exit.
26730 for (; i < groupLength; ++i) {
26731 if (node = group[i]) {
26737 function bindKey(parent, group, enter, update, exit, data, key) {
26740 nodeByKeyValue = {},
26741 groupLength = group.length,
26742 dataLength = data.length,
26743 keyValues = new Array(groupLength),
26746 // Compute the key for each node.
26747 // If multiple nodes have the same key, the duplicates are added to exit.
26748 for (i = 0; i < groupLength; ++i) {
26749 if (node = group[i]) {
26750 keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group);
26751 if (keyValue in nodeByKeyValue) {
26754 nodeByKeyValue[keyValue] = node;
26759 // Compute the key for each datum.
26760 // If there a node associated with this key, join and add it to update.
26761 // If there is not (or the key is a duplicate), add it to enter.
26762 for (i = 0; i < dataLength; ++i) {
26763 keyValue = keyPrefix + key.call(parent, data[i], i, data);
26764 if (node = nodeByKeyValue[keyValue]) {
26766 node.__data__ = data[i];
26767 nodeByKeyValue[keyValue] = null;
26769 enter[i] = new EnterNode(parent, data[i]);
26773 // Add any remaining nodes that were not bound to data to exit.
26774 for (i = 0; i < groupLength; ++i) {
26775 if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) {
26781 var selection_data = function(value, key) {
26783 data = new Array(this.size()), j = -1;
26784 this.each(function(d) { data[++j] = d; });
26788 var bind = key ? bindKey : bindIndex,
26789 parents = this._parents,
26790 groups = this._groups;
26792 if (typeof value !== "function") value = constant$5(value);
26794 for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {
26795 var parent = parents[j],
26797 groupLength = group.length,
26798 data = value.call(parent, parent && parent.__data__, j, parents),
26799 dataLength = data.length,
26800 enterGroup = enter[j] = new Array(dataLength),
26801 updateGroup = update[j] = new Array(dataLength),
26802 exitGroup = exit[j] = new Array(groupLength);
26804 bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);
26806 // Now connect the enter nodes to their following update node, such that
26807 // appendChild can insert the materialized enter node before this node,
26808 // rather than at the end of the parent node.
26809 for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {
26810 if (previous = enterGroup[i0]) {
26811 if (i0 >= i1) i1 = i0 + 1;
26812 while (!(next = updateGroup[i1]) && ++i1 < dataLength);
26813 previous._next = next || null;
26818 update = new Selection(update, parents);
26819 update._enter = enter;
26820 update._exit = exit;
26824 var selection_exit = function() {
26825 return new Selection(this._exit || this._groups.map(sparse), this._parents);
26828 var selection_merge = function(selection) {
26830 for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {
26831 for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
26832 if (node = group0[i] || group1[i]) {
26838 for (; j < m0; ++j) {
26839 merges[j] = groups0[j];
26842 return new Selection(merges, this._parents);
26845 var selection_order = function() {
26847 for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) {
26848 for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) {
26849 if (node = group[i]) {
26850 if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);
26859 var selection_sort = function(compare) {
26860 if (!compare) compare = ascending$2;
26862 function compareNode(a, b) {
26863 return a && b ? compare(a.__data__, b.__data__) : !a - !b;
26866 for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {
26867 for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {
26868 if (node = group[i]) {
26869 sortgroup[i] = node;
26872 sortgroup.sort(compareNode);
26875 return new Selection(sortgroups, this._parents).order();
26878 function ascending$2(a, b) {
26879 return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
26882 var selection_call = function() {
26883 var callback = arguments[0];
26884 arguments[0] = this;
26885 callback.apply(null, arguments);
26889 var selection_nodes = function() {
26890 var nodes = new Array(this.size()), i = -1;
26891 this.each(function() { nodes[++i] = this; });
26895 var selection_node = function() {
26897 for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
26898 for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {
26899 var node = group[i];
26900 if (node) return node;
26907 var selection_size = function() {
26909 this.each(function() { ++size; });
26913 var selection_empty = function() {
26914 return !this.node();
26917 var selection_each = function(callback) {
26919 for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
26920 for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {
26921 if (node = group[i]) callback.call(node, node.__data__, i, group);
26928 function attrRemove(name) {
26929 return function() {
26930 this.removeAttribute(name);
26934 function attrRemoveNS(fullname) {
26935 return function() {
26936 this.removeAttributeNS(fullname.space, fullname.local);
26940 function attrConstant(name, value) {
26941 return function() {
26942 this.setAttribute(name, value);
26946 function attrConstantNS(fullname, value) {
26947 return function() {
26948 this.setAttributeNS(fullname.space, fullname.local, value);
26952 function attrFunction(name, value) {
26953 return function() {
26954 var v = value.apply(this, arguments);
26955 if (v == null) this.removeAttribute(name);
26956 else this.setAttribute(name, v);
26960 function attrFunctionNS(fullname, value) {
26961 return function() {
26962 var v = value.apply(this, arguments);
26963 if (v == null) this.removeAttributeNS(fullname.space, fullname.local);
26964 else this.setAttributeNS(fullname.space, fullname.local, v);
26968 var selection_attr = function(name, value) {
26969 var fullname = namespace(name);
26971 if (arguments.length < 2) {
26972 var node = this.node();
26973 return fullname.local
26974 ? node.getAttributeNS(fullname.space, fullname.local)
26975 : node.getAttribute(fullname);
26978 return this.each((value == null
26979 ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function"
26980 ? (fullname.local ? attrFunctionNS : attrFunction)
26981 : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));
26984 var window$1 = function(node) {
26985 return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node
26986 || (node.document && node) // node is a Window
26987 || node.defaultView; // node is a Document
26990 function styleRemove(name) {
26991 return function() {
26992 this.style.removeProperty(name);
26996 function styleConstant(name, value, priority) {
26997 return function() {
26998 this.style.setProperty(name, value, priority);
27002 function styleFunction(name, value, priority) {
27003 return function() {
27004 var v = value.apply(this, arguments);
27005 if (v == null) this.style.removeProperty(name);
27006 else this.style.setProperty(name, v, priority);
27010 var selection_style = function(name, value, priority) {
27012 return arguments.length > 1
27013 ? this.each((value == null
27014 ? styleRemove : typeof value === "function"
27016 : styleConstant)(name, value, priority == null ? "" : priority))
27017 : window$1(node = this.node())
27018 .getComputedStyle(node, null)
27019 .getPropertyValue(name);
27022 function propertyRemove(name) {
27023 return function() {
27028 function propertyConstant(name, value) {
27029 return function() {
27030 this[name] = value;
27034 function propertyFunction(name, value) {
27035 return function() {
27036 var v = value.apply(this, arguments);
27037 if (v == null) delete this[name];
27038 else this[name] = v;
27042 var selection_property = function(name, value) {
27043 return arguments.length > 1
27044 ? this.each((value == null
27045 ? propertyRemove : typeof value === "function"
27047 : propertyConstant)(name, value))
27048 : this.node()[name];
27051 function classArray(string) {
27052 return string.trim().split(/^|\s+/);
27055 function classList(node) {
27056 return node.classList || new ClassList(node);
27059 function ClassList(node) {
27061 this._names = classArray(node.getAttribute("class") || "");
27064 ClassList.prototype = {
27065 add: function(name) {
27066 var i = this._names.indexOf(name);
27068 this._names.push(name);
27069 this._node.setAttribute("class", this._names.join(" "));
27072 remove: function(name) {
27073 var i = this._names.indexOf(name);
27075 this._names.splice(i, 1);
27076 this._node.setAttribute("class", this._names.join(" "));
27079 contains: function(name) {
27080 return this._names.indexOf(name) >= 0;
27084 function classedAdd(node, names) {
27085 var list = classList(node), i = -1, n = names.length;
27086 while (++i < n) list.add(names[i]);
27089 function classedRemove(node, names) {
27090 var list = classList(node), i = -1, n = names.length;
27091 while (++i < n) list.remove(names[i]);
27094 function classedTrue(names) {
27095 return function() {
27096 classedAdd(this, names);
27100 function classedFalse(names) {
27101 return function() {
27102 classedRemove(this, names);
27106 function classedFunction(names, value) {
27107 return function() {
27108 (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);
27112 var selection_classed = function(name, value) {
27113 var names = classArray(name + "");
27115 if (arguments.length < 2) {
27116 var list = classList(this.node()), i = -1, n = names.length;
27117 while (++i < n) if (!list.contains(names[i])) return false;
27121 return this.each((typeof value === "function"
27122 ? classedFunction : value
27124 : classedFalse)(names, value));
27127 function textRemove() {
27128 this.textContent = "";
27131 function textConstant(value) {
27132 return function() {
27133 this.textContent = value;
27137 function textFunction(value) {
27138 return function() {
27139 var v = value.apply(this, arguments);
27140 this.textContent = v == null ? "" : v;
27144 var selection_text = function(value) {
27145 return arguments.length
27146 ? this.each(value == null
27147 ? textRemove : (typeof value === "function"
27149 : textConstant)(value))
27150 : this.node().textContent;
27153 function htmlRemove() {
27154 this.innerHTML = "";
27157 function htmlConstant(value) {
27158 return function() {
27159 this.innerHTML = value;
27163 function htmlFunction(value) {
27164 return function() {
27165 var v = value.apply(this, arguments);
27166 this.innerHTML = v == null ? "" : v;
27170 var selection_html = function(value) {
27171 return arguments.length
27172 ? this.each(value == null
27173 ? htmlRemove : (typeof value === "function"
27175 : htmlConstant)(value))
27176 : this.node().innerHTML;
27179 function raise$1() {
27180 if (this.nextSibling) this.parentNode.appendChild(this);
27183 var selection_raise = function() {
27184 return this.each(raise$1);
27188 if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);
27191 var selection_lower = function() {
27192 return this.each(lower);
27195 var selection_append = function(name) {
27196 var create = typeof name === "function" ? name : creator(name);
27197 return this.select(function() {
27198 return this.appendChild(create.apply(this, arguments));
27202 function constantNull() {
27206 var selection_insert = function(name, before) {
27207 var create = typeof name === "function" ? name : creator(name),
27208 select = before == null ? constantNull : typeof before === "function" ? before : selector(before);
27209 return this.select(function() {
27210 return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);
27214 function remove() {
27215 var parent = this.parentNode;
27216 if (parent) parent.removeChild(this);
27219 var selection_remove = function() {
27220 return this.each(remove);
27223 var selection_datum = function(value) {
27224 return arguments.length
27225 ? this.property("__data__", value)
27226 : this.node().__data__;
27229 function dispatchEvent(node, type, params) {
27230 var window = window$1(node),
27231 event = window.CustomEvent;
27234 event = new event(type, params);
27236 event = window.document.createEvent("Event");
27237 if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;
27238 else event.initEvent(type, false, false);
27241 node.dispatchEvent(event);
27244 function dispatchConstant(type, params) {
27245 return function() {
27246 return dispatchEvent(this, type, params);
27250 function dispatchFunction(type, params) {
27251 return function() {
27252 return dispatchEvent(this, type, params.apply(this, arguments));
27256 var selection_dispatch = function(type, params) {
27257 return this.each((typeof params === "function"
27259 : dispatchConstant)(type, params));
27264 function Selection(groups, parents) {
27265 this._groups = groups;
27266 this._parents = parents;
27269 function selection() {
27270 return new Selection([[document.documentElement]], root);
27273 Selection.prototype = selection.prototype = {
27274 constructor: Selection,
27275 select: selection_select,
27276 selectAll: selection_selectAll,
27277 filter: selection_filter,
27278 data: selection_data,
27279 enter: selection_enter,
27280 exit: selection_exit,
27281 merge: selection_merge,
27282 order: selection_order,
27283 sort: selection_sort,
27284 call: selection_call,
27285 nodes: selection_nodes,
27286 node: selection_node,
27287 size: selection_size,
27288 empty: selection_empty,
27289 each: selection_each,
27290 attr: selection_attr,
27291 style: selection_style,
27292 property: selection_property,
27293 classed: selection_classed,
27294 text: selection_text,
27295 html: selection_html,
27296 raise: selection_raise,
27297 lower: selection_lower,
27298 append: selection_append,
27299 insert: selection_insert,
27300 remove: selection_remove,
27301 datum: selection_datum,
27303 dispatch: selection_dispatch
27306 var select = function(selector) {
27307 return typeof selector === "string"
27308 ? new Selection([[document.querySelector(selector)]], [document.documentElement])
27309 : new Selection([[selector]], root);
27312 var selectAll = function(selector) {
27313 return typeof selector === "string"
27314 ? new Selection([document.querySelectorAll(selector)], [document.documentElement])
27315 : new Selection([selector == null ? [] : selector], root);
27318 var touch = function(node, touches, identifier) {
27319 if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches;
27321 for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) {
27322 if ((touch = touches[i]).identifier === identifier) {
27323 return point$5(node, touch);
27330 var touches = function(node, touches) {
27331 if (touches == null) touches = sourceEvent().touches;
27333 for (var i = 0, n = touches ? touches.length : 0, points = new Array(n); i < n; ++i) {
27334 points[i] = point$5(node, touches[i]);
27340 var emptyOn = dispatch("start", "end", "interrupt");
27341 var emptyTween = [];
27351 var schedule = function(node, name, id, index, group, timing) {
27352 var schedules = node.__transition;
27353 if (!schedules) node.__transition = {};
27354 else if (id in schedules) return;
27357 index: index, // For context during callback.
27358 group: group, // For context during callback.
27362 delay: timing.delay,
27363 duration: timing.duration,
27370 function init(node, id) {
27371 var schedule = node.__transition;
27372 if (!schedule || !(schedule = schedule[id]) || schedule.state > CREATED) throw new Error("too late");
27376 function set$3(node, id) {
27377 var schedule = node.__transition;
27378 if (!schedule || !(schedule = schedule[id]) || schedule.state > STARTING) throw new Error("too late");
27382 function get$1(node, id) {
27383 var schedule = node.__transition;
27384 if (!schedule || !(schedule = schedule[id])) throw new Error("too late");
27388 function create(node, id, self) {
27389 var schedules = node.__transition,
27392 // Initialize the self timer when the transition is created.
27393 // Note the actual delay is not known until the first callback!
27394 schedules[id] = self;
27395 self.timer = timer(schedule, 0, self.time);
27397 function schedule(elapsed) {
27398 self.state = SCHEDULED;
27399 self.timer.restart(start, self.delay, self.time);
27401 // If the elapsed delay is less than our first sleep, start immediately.
27402 if (self.delay <= elapsed) start(elapsed - self.delay);
27405 function start(elapsed) {
27408 // If the state is not SCHEDULED, then we previously errored on start.
27409 if (self.state !== SCHEDULED) return stop();
27411 for (i in schedules) {
27413 if (o.name !== self.name) continue;
27415 // While this element already has a starting transition during this frame,
27416 // defer starting an interrupting transition until that transition has a
27417 // chance to tick (and possibly end); see d3/d3-transition#54!
27418 if (o.state === STARTED) return timeout$1(start);
27420 // Interrupt the active transition, if any.
27421 // Dispatch the interrupt event.
27422 if (o.state === RUNNING) {
27425 o.on.call("interrupt", node, node.__data__, o.index, o.group);
27426 delete schedules[i];
27429 // Cancel any pre-empted transitions. No interrupt event is dispatched
27430 // because the cancelled transitions never started. Note that this also
27431 // removes this transition from the pending list!
27432 else if (+i < id) {
27435 delete schedules[i];
27439 // Defer the first tick to end of the current frame; see d3/d3#1576.
27440 // Note the transition may be canceled after start and before the first tick!
27441 // Note this must be scheduled before the start event; see d3/d3-transition#16!
27442 // Assuming this is successful, subsequent callbacks go straight to tick.
27443 timeout$1(function() {
27444 if (self.state === STARTED) {
27445 self.state = RUNNING;
27446 self.timer.restart(tick, self.delay, self.time);
27451 // Dispatch the start event.
27452 // Note this must be done before the tween are initialized.
27453 self.state = STARTING;
27454 self.on.call("start", node, node.__data__, self.index, self.group);
27455 if (self.state !== STARTING) return; // interrupted
27456 self.state = STARTED;
27458 // Initialize the tween, deleting null tween.
27459 tween = new Array(n = self.tween.length);
27460 for (i = 0, j = -1; i < n; ++i) {
27461 if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) {
27465 tween.length = j + 1;
27468 function tick(elapsed) {
27469 var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1),
27474 tween[i].call(null, t);
27477 // Dispatch the end event.
27478 if (self.state === ENDING) {
27479 self.on.call("end", node, node.__data__, self.index, self.group);
27485 self.state = ENDED;
27487 delete schedules[id];
27488 for (var i in schedules) return; // eslint-disable-line no-unused-vars
27489 delete node.__transition;
27493 var interrupt = function(node, name) {
27494 var schedules = node.__transition,
27500 if (!schedules) return;
27502 name = name == null ? null : name + "";
27504 for (i in schedules) {
27505 if ((schedule = schedules[i]).name !== name) { empty = false; continue; }
27506 active = schedule.state > STARTING && schedule.state < ENDING;
27507 schedule.state = ENDED;
27508 schedule.timer.stop();
27509 if (active) schedule.on.call("interrupt", node, node.__data__, schedule.index, schedule.group);
27510 delete schedules[i];
27513 if (empty) delete node.__transition;
27516 var selection_interrupt = function(name) {
27517 return this.each(function() {
27518 interrupt(this, name);
27522 function tweenRemove(id, name) {
27523 var tween0, tween1;
27524 return function() {
27525 var schedule = set$3(this, id),
27526 tween = schedule.tween;
27528 // If this node shared tween with the previous node,
27529 // just assign the updated shared tween and we’re done!
27530 // Otherwise, copy-on-write.
27531 if (tween !== tween0) {
27532 tween1 = tween0 = tween;
27533 for (var i = 0, n = tween1.length; i < n; ++i) {
27534 if (tween1[i].name === name) {
27535 tween1 = tween1.slice();
27536 tween1.splice(i, 1);
27542 schedule.tween = tween1;
27546 function tweenFunction(id, name, value) {
27547 var tween0, tween1;
27548 if (typeof value !== "function") throw new Error;
27549 return function() {
27550 var schedule = set$3(this, id),
27551 tween = schedule.tween;
27553 // If this node shared tween with the previous node,
27554 // just assign the updated shared tween and we’re done!
27555 // Otherwise, copy-on-write.
27556 if (tween !== tween0) {
27557 tween1 = (tween0 = tween).slice();
27558 for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) {
27559 if (tween1[i].name === name) {
27564 if (i === n) tween1.push(t);
27567 schedule.tween = tween1;
27571 var transition_tween = function(name, value) {
27576 if (arguments.length < 2) {
27577 var tween = get$1(this.node(), id).tween;
27578 for (var i = 0, n = tween.length, t; i < n; ++i) {
27579 if ((t = tween[i]).name === name) {
27586 return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value));
27589 function tweenValue(transition, name, value) {
27590 var id = transition._id;
27592 transition.each(function() {
27593 var schedule = set$3(this, id);
27594 (schedule.value || (schedule.value = {}))[name] = value.apply(this, arguments);
27597 return function(node) {
27598 return get$1(node, id).value[name];
27602 var interpolate$1 = function(a, b) {
27604 return (typeof b === "number" ? interpolateNumber
27605 : b instanceof color ? interpolateRgb
27606 : (c = color(b)) ? (b = c, interpolateRgb)
27607 : interpolateString)(a, b);
27610 function attrRemove$1(name) {
27611 return function() {
27612 this.removeAttribute(name);
27616 function attrRemoveNS$1(fullname) {
27617 return function() {
27618 this.removeAttributeNS(fullname.space, fullname.local);
27622 function attrConstant$1(name, interpolate$$1, value1) {
27625 return function() {
27626 var value0 = this.getAttribute(name);
27627 return value0 === value1 ? null
27628 : value0 === value00 ? interpolate0
27629 : interpolate0 = interpolate$$1(value00 = value0, value1);
27633 function attrConstantNS$1(fullname, interpolate$$1, value1) {
27636 return function() {
27637 var value0 = this.getAttributeNS(fullname.space, fullname.local);
27638 return value0 === value1 ? null
27639 : value0 === value00 ? interpolate0
27640 : interpolate0 = interpolate$$1(value00 = value0, value1);
27644 function attrFunction$1(name, interpolate$$1, value) {
27648 return function() {
27649 var value0, value1 = value(this);
27650 if (value1 == null) return void this.removeAttribute(name);
27651 value0 = this.getAttribute(name);
27652 return value0 === value1 ? null
27653 : value0 === value00 && value1 === value10 ? interpolate0
27654 : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
27658 function attrFunctionNS$1(fullname, interpolate$$1, value) {
27662 return function() {
27663 var value0, value1 = value(this);
27664 if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local);
27665 value0 = this.getAttributeNS(fullname.space, fullname.local);
27666 return value0 === value1 ? null
27667 : value0 === value00 && value1 === value10 ? interpolate0
27668 : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
27672 var transition_attr = function(name, value) {
27673 var fullname = namespace(name), i = fullname === "transform" ? interpolateTransformSvg : interpolate$1;
27674 return this.attrTween(name, typeof value === "function"
27675 ? (fullname.local ? attrFunctionNS$1 : attrFunction$1)(fullname, i, tweenValue(this, "attr." + name, value))
27676 : value == null ? (fullname.local ? attrRemoveNS$1 : attrRemove$1)(fullname)
27677 : (fullname.local ? attrConstantNS$1 : attrConstant$1)(fullname, i, value));
27680 function attrTweenNS(fullname, value) {
27682 var node = this, i = value.apply(node, arguments);
27683 return i && function(t) {
27684 node.setAttributeNS(fullname.space, fullname.local, i(t));
27687 tween._value = value;
27691 function attrTween(name, value) {
27693 var node = this, i = value.apply(node, arguments);
27694 return i && function(t) {
27695 node.setAttribute(name, i(t));
27698 tween._value = value;
27702 var transition_attrTween = function(name, value) {
27703 var key = "attr." + name;
27704 if (arguments.length < 2) return (key = this.tween(key)) && key._value;
27705 if (value == null) return this.tween(key, null);
27706 if (typeof value !== "function") throw new Error;
27707 var fullname = namespace(name);
27708 return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value));
27711 function delayFunction(id, value) {
27712 return function() {
27713 init(this, id).delay = +value.apply(this, arguments);
27717 function delayConstant(id, value) {
27718 return value = +value, function() {
27719 init(this, id).delay = value;
27723 var transition_delay = function(value) {
27726 return arguments.length
27727 ? this.each((typeof value === "function"
27729 : delayConstant)(id, value))
27730 : get$1(this.node(), id).delay;
27733 function durationFunction(id, value) {
27734 return function() {
27735 set$3(this, id).duration = +value.apply(this, arguments);
27739 function durationConstant(id, value) {
27740 return value = +value, function() {
27741 set$3(this, id).duration = value;
27745 var transition_duration = function(value) {
27748 return arguments.length
27749 ? this.each((typeof value === "function"
27751 : durationConstant)(id, value))
27752 : get$1(this.node(), id).duration;
27755 function easeConstant(id, value) {
27756 if (typeof value !== "function") throw new Error;
27757 return function() {
27758 set$3(this, id).ease = value;
27762 var transition_ease = function(value) {
27765 return arguments.length
27766 ? this.each(easeConstant(id, value))
27767 : get$1(this.node(), id).ease;
27770 var transition_filter = function(match) {
27771 if (typeof match !== "function") match = matcher$1(match);
27773 for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
27774 for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
27775 if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
27776 subgroup.push(node);
27781 return new Transition(subgroups, this._parents, this._name, this._id);
27784 var transition_merge = function(transition) {
27785 if (transition._id !== this._id) throw new Error;
27787 for (var groups0 = this._groups, groups1 = transition._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {
27788 for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
27789 if (node = group0[i] || group1[i]) {
27795 for (; j < m0; ++j) {
27796 merges[j] = groups0[j];
27799 return new Transition(merges, this._parents, this._name, this._id);
27802 function start$1(name) {
27803 return (name + "").trim().split(/^|\s+/).every(function(t) {
27804 var i = t.indexOf(".");
27805 if (i >= 0) t = t.slice(0, i);
27806 return !t || t === "start";
27810 function onFunction(id, name, listener) {
27811 var on0, on1, sit = start$1(name) ? init : set$3;
27812 return function() {
27813 var schedule = sit(this, id),
27816 // If this node shared a dispatch with the previous node,
27817 // just assign the updated shared dispatch and we’re done!
27818 // Otherwise, copy-on-write.
27819 if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener);
27825 var transition_on = function(name, listener) {
27828 return arguments.length < 2
27829 ? get$1(this.node(), id).on.on(name)
27830 : this.each(onFunction(id, name, listener));
27833 function removeFunction(id) {
27834 return function() {
27835 var parent = this.parentNode;
27836 for (var i in this.__transition) if (+i !== id) return;
27837 if (parent) parent.removeChild(this);
27841 var transition_remove = function() {
27842 return this.on("end.remove", removeFunction(this._id));
27845 var transition_select = function(select$$1) {
27846 var name = this._name,
27849 if (typeof select$$1 !== "function") select$$1 = selector(select$$1);
27851 for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
27852 for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
27853 if ((node = group[i]) && (subnode = select$$1.call(node, node.__data__, i, group))) {
27854 if ("__data__" in node) subnode.__data__ = node.__data__;
27855 subgroup[i] = subnode;
27856 schedule(subgroup[i], name, id, i, subgroup, get$1(node, id));
27861 return new Transition(subgroups, this._parents, name, id);
27864 var transition_selectAll = function(select$$1) {
27865 var name = this._name,
27868 if (typeof select$$1 !== "function") select$$1 = selectorAll(select$$1);
27870 for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
27871 for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
27872 if (node = group[i]) {
27873 for (var children = select$$1.call(node, node.__data__, i, group), child, inherit = get$1(node, id), k = 0, l = children.length; k < l; ++k) {
27874 if (child = children[k]) {
27875 schedule(child, name, id, k, children, inherit);
27878 subgroups.push(children);
27879 parents.push(node);
27884 return new Transition(subgroups, parents, name, id);
27887 var Selection$1 = selection.prototype.constructor;
27889 var transition_selection = function() {
27890 return new Selection$1(this._groups, this._parents);
27893 function styleRemove$1(name, interpolate$$1) {
27897 return function() {
27898 var style = window$1(this).getComputedStyle(this, null),
27899 value0 = style.getPropertyValue(name),
27900 value1 = (this.style.removeProperty(name), style.getPropertyValue(name));
27901 return value0 === value1 ? null
27902 : value0 === value00 && value1 === value10 ? interpolate0
27903 : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
27907 function styleRemoveEnd(name) {
27908 return function() {
27909 this.style.removeProperty(name);
27913 function styleConstant$1(name, interpolate$$1, value1) {
27916 return function() {
27917 var value0 = window$1(this).getComputedStyle(this, null).getPropertyValue(name);
27918 return value0 === value1 ? null
27919 : value0 === value00 ? interpolate0
27920 : interpolate0 = interpolate$$1(value00 = value0, value1);
27924 function styleFunction$1(name, interpolate$$1, value) {
27928 return function() {
27929 var style = window$1(this).getComputedStyle(this, null),
27930 value0 = style.getPropertyValue(name),
27931 value1 = value(this);
27932 if (value1 == null) value1 = (this.style.removeProperty(name), style.getPropertyValue(name));
27933 return value0 === value1 ? null
27934 : value0 === value00 && value1 === value10 ? interpolate0
27935 : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
27939 var transition_style = function(name, value, priority) {
27940 var i = (name += "") === "transform" ? interpolateTransformCss : interpolate$1;
27941 return value == null ? this
27942 .styleTween(name, styleRemove$1(name, i))
27943 .on("end.style." + name, styleRemoveEnd(name))
27944 : this.styleTween(name, typeof value === "function"
27945 ? styleFunction$1(name, i, tweenValue(this, "style." + name, value))
27946 : styleConstant$1(name, i, value), priority);
27949 function styleTween(name, value, priority) {
27951 var node = this, i = value.apply(node, arguments);
27952 return i && function(t) {
27953 node.style.setProperty(name, i(t), priority);
27956 tween._value = value;
27960 var transition_styleTween = function(name, value, priority) {
27961 var key = "style." + (name += "");
27962 if (arguments.length < 2) return (key = this.tween(key)) && key._value;
27963 if (value == null) return this.tween(key, null);
27964 if (typeof value !== "function") throw new Error;
27965 return this.tween(key, styleTween(name, value, priority == null ? "" : priority));
27968 function textConstant$1(value) {
27969 return function() {
27970 this.textContent = value;
27974 function textFunction$1(value) {
27975 return function() {
27976 var value1 = value(this);
27977 this.textContent = value1 == null ? "" : value1;
27981 var transition_text = function(value) {
27982 return this.tween("text", typeof value === "function"
27983 ? textFunction$1(tweenValue(this, "text", value))
27984 : textConstant$1(value == null ? "" : value + ""));
27987 var transition_transition = function() {
27988 var name = this._name,
27992 for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {
27993 for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
27994 if (node = group[i]) {
27995 var inherit = get$1(node, id0);
27996 schedule(node, name, id1, i, group, {
27997 time: inherit.time + inherit.delay + inherit.duration,
27999 duration: inherit.duration,
28006 return new Transition(groups, this._parents, name, id1);
28011 function Transition(groups, parents, name, id) {
28012 this._groups = groups;
28013 this._parents = parents;
28018 function transition(name) {
28019 return selection().transition(name);
28026 var selection_prototype = selection.prototype;
28028 Transition.prototype = transition.prototype = {
28029 constructor: Transition,
28030 select: transition_select,
28031 selectAll: transition_selectAll,
28032 filter: transition_filter,
28033 merge: transition_merge,
28034 selection: transition_selection,
28035 transition: transition_transition,
28036 call: selection_prototype.call,
28037 nodes: selection_prototype.nodes,
28038 node: selection_prototype.node,
28039 size: selection_prototype.size,
28040 empty: selection_prototype.empty,
28041 each: selection_prototype.each,
28043 attr: transition_attr,
28044 attrTween: transition_attrTween,
28045 style: transition_style,
28046 styleTween: transition_styleTween,
28047 text: transition_text,
28048 remove: transition_remove,
28049 tween: transition_tween,
28050 delay: transition_delay,
28051 duration: transition_duration,
28052 ease: transition_ease
28055 var defaultTiming = {
28056 time: null, // Set on use.
28062 function inherit(node, id) {
28064 while (!(timing = node.__transition) || !(timing = timing[id])) {
28065 if (!(node = node.parentNode)) {
28066 return defaultTiming.time = now(), defaultTiming;
28072 var selection_transition = function(name) {
28076 if (name instanceof Transition) {
28077 id = name._id, name = name._name;
28079 id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + "";
28082 for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {
28083 for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
28084 if (node = group[i]) {
28085 schedule(node, name, id, i, group, timing || inherit(node, id));
28090 return new Transition(groups, this._parents, name, id);
28093 selection.prototype.interrupt = selection_interrupt;
28094 selection.prototype.transition = selection_transition;
28096 var root$1 = [null];
28098 var active = function(node, name) {
28099 var schedules = node.__transition,
28104 name = name == null ? null : name + "";
28105 for (i in schedules) {
28106 if ((schedule = schedules[i]).state > SCHEDULED && schedule.name === name) {
28107 return new Transition([[node]], root$1, name, +i);
28115 var slice$4 = Array.prototype.slice;
28117 var identity$5 = function(x) {
28125 var epsilon$2 = 1e-6;
28127 function translateX(scale0, scale1, d) {
28129 return "translate(" + (isFinite(x) ? x : scale1(d)) + ",0)";
28132 function translateY(scale0, scale1, d) {
28134 return "translate(0," + (isFinite(y) ? y : scale1(d)) + ")";
28137 function center(scale) {
28138 var offset = scale.bandwidth() / 2;
28139 if (scale.round()) offset = Math.round(offset);
28140 return function(d) {
28141 return scale(d) + offset;
28145 function entering() {
28146 return !this.__axis;
28149 function axis(orient, scale) {
28150 var tickArguments = [],
28157 function axis(context) {
28158 var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues,
28159 format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity$5) : tickFormat,
28160 spacing = Math.max(tickSizeInner, 0) + tickPadding,
28161 transform = orient === top || orient === bottom ? translateX : translateY,
28162 range = scale.range(),
28163 range0 = range[0] + 0.5,
28164 range1 = range[range.length - 1] + 0.5,
28165 position = (scale.bandwidth ? center : identity$5)(scale.copy()),
28166 selection = context.selection ? context.selection() : context,
28167 path = selection.selectAll(".domain").data([null]),
28168 tick = selection.selectAll(".tick").data(values, scale).order(),
28169 tickExit = tick.exit(),
28170 tickEnter = tick.enter().append("g").attr("class", "tick"),
28171 line = tick.select("line"),
28172 text = tick.select("text"),
28173 k = orient === top || orient === left ? -1 : 1,
28174 x, y = orient === left || orient === right ? (x = "x", "y") : (x = "y", "x");
28176 path = path.merge(path.enter().insert("path", ".tick")
28177 .attr("class", "domain")
28178 .attr("stroke", "#000"));
28180 tick = tick.merge(tickEnter);
28182 line = line.merge(tickEnter.append("line")
28183 .attr("stroke", "#000")
28184 .attr(x + "2", k * tickSizeInner)
28185 .attr(y + "1", 0.5)
28186 .attr(y + "2", 0.5));
28188 text = text.merge(tickEnter.append("text")
28189 .attr("fill", "#000")
28190 .attr(x, k * spacing)
28192 .attr("dy", orient === top ? "0em" : orient === bottom ? "0.71em" : "0.32em"));
28194 if (context !== selection) {
28195 path = path.transition(context);
28196 tick = tick.transition(context);
28197 line = line.transition(context);
28198 text = text.transition(context);
28200 tickExit = tickExit.transition(context)
28201 .attr("opacity", epsilon$2)
28202 .attr("transform", function(d) { return transform(position, this.parentNode.__axis || position, d); });
28205 .attr("opacity", epsilon$2)
28206 .attr("transform", function(d) { return transform(this.parentNode.__axis || position, position, d); });
28212 .attr("d", orient === left || orient == right
28213 ? "M" + k * tickSizeOuter + "," + range0 + "H0.5V" + range1 + "H" + k * tickSizeOuter
28214 : "M" + range0 + "," + k * tickSizeOuter + "V0.5H" + range1 + "V" + k * tickSizeOuter);
28217 .attr("opacity", 1)
28218 .attr("transform", function(d) { return transform(position, position, d); });
28221 .attr(x + "2", k * tickSizeInner);
28224 .attr(x, k * spacing)
28227 selection.filter(entering)
28228 .attr("fill", "none")
28229 .attr("font-size", 10)
28230 .attr("font-family", "sans-serif")
28231 .attr("text-anchor", orient === right ? "start" : orient === left ? "end" : "middle");
28234 .each(function() { this.__axis = position; });
28237 axis.scale = function(_) {
28238 return arguments.length ? (scale = _, axis) : scale;
28241 axis.ticks = function() {
28242 return tickArguments = slice$4.call(arguments), axis;
28245 axis.tickArguments = function(_) {
28246 return arguments.length ? (tickArguments = _ == null ? [] : slice$4.call(_), axis) : tickArguments.slice();
28249 axis.tickValues = function(_) {
28250 return arguments.length ? (tickValues = _ == null ? null : slice$4.call(_), axis) : tickValues && tickValues.slice();
28253 axis.tickFormat = function(_) {
28254 return arguments.length ? (tickFormat = _, axis) : tickFormat;
28257 axis.tickSize = function(_) {
28258 return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner;
28261 axis.tickSizeInner = function(_) {
28262 return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner;
28265 axis.tickSizeOuter = function(_) {
28266 return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter;
28269 axis.tickPadding = function(_) {
28270 return arguments.length ? (tickPadding = +_, axis) : tickPadding;
28276 function axisTop(scale) {
28277 return axis(top, scale);
28280 function axisRight(scale) {
28281 return axis(right, scale);
28284 function axisBottom(scale) {
28285 return axis(bottom, scale);
28288 function axisLeft(scale) {
28289 return axis(left, scale);
28292 function defaultSeparation(a, b) {
28293 return a.parent === b.parent ? 1 : 2;
28296 function meanX(children) {
28297 return children.reduce(meanXReduce, 0) / children.length;
28300 function meanXReduce(x, c) {
28304 function maxY(children) {
28305 return 1 + children.reduce(maxYReduce, 0);
28308 function maxYReduce(y, c) {
28309 return Math.max(y, c.y);
28312 function leafLeft(node) {
28314 while (children = node.children) node = children[0];
28318 function leafRight(node) {
28320 while (children = node.children) node = children[children.length - 1];
28324 var cluster = function() {
28325 var separation = defaultSeparation,
28330 function cluster(root) {
28334 // First walk, computing the initial x & y values.
28335 root.eachAfter(function(node) {
28336 var children = node.children;
28338 node.x = meanX(children);
28339 node.y = maxY(children);
28341 node.x = previousNode ? x += separation(node, previousNode) : 0;
28343 previousNode = node;
28347 var left = leafLeft(root),
28348 right = leafRight(root),
28349 x0 = left.x - separation(left, right) / 2,
28350 x1 = right.x + separation(right, left) / 2;
28352 // Second walk, normalizing x & y to the desired size.
28353 return root.eachAfter(nodeSize ? function(node) {
28354 node.x = (node.x - root.x) * dx;
28355 node.y = (root.y - node.y) * dy;
28356 } : function(node) {
28357 node.x = (node.x - x0) / (x1 - x0) * dx;
28358 node.y = (1 - (root.y ? node.y / root.y : 1)) * dy;
28362 cluster.separation = function(x) {
28363 return arguments.length ? (separation = x, cluster) : separation;
28366 cluster.size = function(x) {
28367 return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? null : [dx, dy]);
28370 cluster.nodeSize = function(x) {
28371 return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? [dx, dy] : null);
28377 var node_each = function(callback) {
28378 var node = this, current, next = [node], children, i, n;
28380 current = next.reverse(), next = [];
28381 while (node = current.pop()) {
28382 callback(node), children = node.children;
28383 if (children) for (i = 0, n = children.length; i < n; ++i) {
28384 next.push(children[i]);
28387 } while (next.length);
28391 var node_eachBefore = function(callback) {
28392 var node = this, nodes = [node], children, i;
28393 while (node = nodes.pop()) {
28394 callback(node), children = node.children;
28395 if (children) for (i = children.length - 1; i >= 0; --i) {
28396 nodes.push(children[i]);
28402 var node_eachAfter = function(callback) {
28403 var node = this, nodes = [node], next = [], children, i, n;
28404 while (node = nodes.pop()) {
28405 next.push(node), children = node.children;
28406 if (children) for (i = 0, n = children.length; i < n; ++i) {
28407 nodes.push(children[i]);
28410 while (node = next.pop()) {
28416 var node_sum = function(value) {
28417 return this.eachAfter(function(node) {
28418 var sum = +value(node.data) || 0,
28419 children = node.children,
28420 i = children && children.length;
28421 while (--i >= 0) sum += children[i].value;
28426 var node_sort = function(compare) {
28427 return this.eachBefore(function(node) {
28428 if (node.children) {
28429 node.children.sort(compare);
28434 var node_path = function(end) {
28436 ancestor = leastCommonAncestor(start, end),
28438 while (start !== ancestor) {
28439 start = start.parent;
28442 var k = nodes.length;
28443 while (end !== ancestor) {
28444 nodes.splice(k, 0, end);
28450 function leastCommonAncestor(a, b) {
28451 if (a === b) return a;
28452 var aNodes = a.ancestors(),
28453 bNodes = b.ancestors(),
28465 var node_ancestors = function() {
28466 var node = this, nodes = [node];
28467 while (node = node.parent) {
28473 var node_descendants = function() {
28475 this.each(function(node) {
28481 var node_leaves = function() {
28483 this.eachBefore(function(node) {
28484 if (!node.children) {
28491 var node_links = function() {
28492 var root = this, links = [];
28493 root.each(function(node) {
28494 if (node !== root) { // Don’t include the root’s parent, if any.
28495 links.push({source: node.parent, target: node});
28501 function hierarchy(data, children) {
28502 var root = new Node(data),
28503 valued = +data.value && (root.value = data.value),
28511 if (children == null) children = defaultChildren;
28513 while (node = nodes.pop()) {
28514 if (valued) node.value = +node.data.value;
28515 if ((childs = children(node.data)) && (n = childs.length)) {
28516 node.children = new Array(n);
28517 for (i = n - 1; i >= 0; --i) {
28518 nodes.push(child = node.children[i] = new Node(childs[i]));
28519 child.parent = node;
28520 child.depth = node.depth + 1;
28525 return root.eachBefore(computeHeight);
28528 function node_copy() {
28529 return hierarchy(this).eachBefore(copyData);
28532 function defaultChildren(d) {
28536 function copyData(node) {
28537 node.data = node.data.data;
28540 function computeHeight(node) {
28542 do node.height = height;
28543 while ((node = node.parent) && (node.height < ++height));
28546 function Node(data) {
28550 this.parent = null;
28553 Node.prototype = hierarchy.prototype = {
28556 eachAfter: node_eachAfter,
28557 eachBefore: node_eachBefore,
28561 ancestors: node_ancestors,
28562 descendants: node_descendants,
28563 leaves: node_leaves,
28568 function Node$2(value) {
28573 var shuffle$1 = function(array) {
28575 n = (array = array.slice()).length,
28580 var next = new Node$2(array[n - 1]);
28581 if (node) node = node.next = next;
28582 else node = head = next;
28583 array[i] = array[--n];
28592 var enclose = function(circles) {
28593 return encloseN(shuffle$1(circles), []);
28596 function encloses(a, b) {
28597 var dx = b.x - a.x,
28600 return dr * dr + 1e-6 > dx * dx + dy * dy;
28603 // Returns the smallest circle that contains circles L and intersects circles B.
28604 function encloseN(L, B) {
28611 switch (B.length) {
28612 case 1: circle = enclose1(B[0]); break;
28613 case 2: circle = enclose2(B[0], B[1]); break;
28614 case 3: circle = enclose3(B[0], B[1], B[2]); break;
28618 p1 = l1._, l2 = l1.next;
28619 if (!circle || !encloses(circle, p1)) {
28621 // Temporarily truncate L before l1.
28622 if (l0) L.tail = l0, l0.next = null;
28623 else L.head = L.tail = null;
28626 circle = encloseN(L, B); // Note: reorders L!
28629 // Move l1 to the front of L and reconnect the truncated list L.
28630 if (L.head) l1.next = L.head, L.head = l1;
28631 else l1.next = null, L.head = L.tail = l1;
28632 l0 = L.tail, l0.next = l2;
28644 function enclose1(a) {
28652 function enclose2(a, b) {
28653 var x1 = a.x, y1 = a.y, r1 = a.r,
28654 x2 = b.x, y2 = b.y, r2 = b.r,
28655 x21 = x2 - x1, y21 = y2 - y1, r21 = r2 - r1,
28656 l = Math.sqrt(x21 * x21 + y21 * y21);
28658 x: (x1 + x2 + x21 / l * r21) / 2,
28659 y: (y1 + y2 + y21 / l * r21) / 2,
28660 r: (l + r1 + r2) / 2
28664 function enclose3(a, b, c) {
28665 var x1 = a.x, y1 = a.y, r1 = a.r,
28666 x2 = b.x, y2 = b.y, r2 = b.r,
28667 x3 = c.x, y3 = c.y, r3 = c.r,
28668 a2 = 2 * (x1 - x2),
28669 b2 = 2 * (y1 - y2),
28670 c2 = 2 * (r2 - r1),
28671 d2 = x1 * x1 + y1 * y1 - r1 * r1 - x2 * x2 - y2 * y2 + r2 * r2,
28672 a3 = 2 * (x1 - x3),
28673 b3 = 2 * (y1 - y3),
28674 c3 = 2 * (r3 - r1),
28675 d3 = x1 * x1 + y1 * y1 - r1 * r1 - x3 * x3 - y3 * y3 + r3 * r3,
28676 ab = a3 * b2 - a2 * b3,
28677 xa = (b2 * d3 - b3 * d2) / ab - x1,
28678 xb = (b3 * c2 - b2 * c3) / ab,
28679 ya = (a3 * d2 - a2 * d3) / ab - y1,
28680 yb = (a2 * c3 - a3 * c2) / ab,
28681 A = xb * xb + yb * yb - 1,
28682 B = 2 * (xa * xb + ya * yb + r1),
28683 C = xa * xa + ya * ya - r1 * r1,
28684 r = (-B - Math.sqrt(B * B - 4 * A * C)) / (2 * A);
28686 x: xa + xb * r + x1,
28687 y: ya + yb * r + y1,
28692 function place(a, b, c) {
28699 dc = dx * dx + dy * dy;
28701 var x = 0.5 + ((db *= db) - (da *= da)) / (2 * dc),
28702 y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc);
28703 c.x = ax + x * dx + y * dy;
28704 c.y = ay + x * dy - y * dx;
28711 function intersects(a, b) {
28712 var dx = b.x - a.x,
28715 return dr * dr > dx * dx + dy * dy;
28718 function distance2(circle, x, y) {
28719 var dx = circle.x - x,
28721 return dx * dx + dy * dy;
28724 function Node$1(circle) {
28727 this.previous = null;
28730 function packEnclose(circles) {
28731 if (!(n = circles.length)) return 0;
28735 // Place the first circle.
28736 a = circles[0], a.x = 0, a.y = 0;
28737 if (!(n > 1)) return a.r;
28739 // Place the second circle.
28740 b = circles[1], a.x = -b.r, b.x = a.r, b.y = 0;
28741 if (!(n > 2)) return a.r + b.r;
28743 // Place the third circle.
28744 place(b, a, c = circles[2]);
28746 // Initialize the weighted centroid.
28747 var aa = a.r * a.r,
28751 ox = aa * a.x + ba * b.x + ca * c.x,
28752 oy = aa * a.y + ba * b.y + ca * c.y,
28753 cx, cy, i, j, k, sj, sk;
28755 // Initialize the front-chain using the first three circles a, b and c.
28756 a = new Node$1(a), b = new Node$1(b), c = new Node$1(c);
28757 a.next = c.previous = b;
28758 b.next = a.previous = c;
28759 c.next = b.previous = a;
28761 // Attempt to place each remaining circle…
28762 pack: for (i = 3; i < n; ++i) {
28763 place(a._, b._, c = circles[i]), c = new Node$1(c);
28765 // If there are only three elements in the front-chain…
28766 if ((k = a.previous) === (j = b.next)) {
28767 // If the new circle intersects the third circle,
28768 // rotate the front chain to try the next position.
28769 if (intersects(j._, c._)) {
28775 // Find the closest intersecting circle on the front-chain, if any.
28777 sj = j._.r, sk = k._.r;
28780 if (intersects(j._, c._)) {
28781 b = j, a.next = b, b.previous = a, --i;
28784 j = j.next, sj += j._.r;
28786 if (intersects(k._, c._)) {
28787 a = k, a.next = b, b.previous = a, --i;
28790 k = k.previous, sk += k._.r;
28792 } while (j !== k.next);
28795 // Success! Insert the new circle c between a and b.
28796 c.previous = a, c.next = b, a.next = b.previous = b = c;
28798 // Update the weighted centroid.
28799 oa += ca = c._.r * c._.r;
28803 // Compute the new closest circle a to centroid.
28804 aa = distance2(a._, cx = ox / oa, cy = oy / oa);
28805 while ((c = c.next) !== b) {
28806 if ((ca = distance2(c._, cx, cy)) < aa) {
28813 // Compute the enclosing circle of the front chain.
28814 a = [b._], c = b; while ((c = c.next) !== b) a.push(c._); c = enclose(a);
28816 // Translate the circles to put the enclosing circle around the origin.
28817 for (i = 0; i < n; ++i) a = circles[i], a.x -= c.x, a.y -= c.y;
28822 var siblings = function(circles) {
28823 packEnclose(circles);
28827 function optional(f) {
28828 return f == null ? null : required(f);
28831 function required(f) {
28832 if (typeof f !== "function") throw new Error;
28836 function constantZero() {
28840 var constant$6 = function(x) {
28841 return function() {
28846 function defaultRadius(d) {
28847 return Math.sqrt(d.value);
28850 var index$2 = function() {
28854 padding = constantZero;
28856 function pack(root) {
28857 root.x = dx / 2, root.y = dy / 2;
28859 root.eachBefore(radiusLeaf(radius))
28860 .eachAfter(packChildren(padding, 0.5))
28861 .eachBefore(translateChild(1));
28863 root.eachBefore(radiusLeaf(defaultRadius))
28864 .eachAfter(packChildren(constantZero, 1))
28865 .eachAfter(packChildren(padding, root.r / Math.min(dx, dy)))
28866 .eachBefore(translateChild(Math.min(dx, dy) / (2 * root.r)));
28871 pack.radius = function(x) {
28872 return arguments.length ? (radius = optional(x), pack) : radius;
28875 pack.size = function(x) {
28876 return arguments.length ? (dx = +x[0], dy = +x[1], pack) : [dx, dy];
28879 pack.padding = function(x) {
28880 return arguments.length ? (padding = typeof x === "function" ? x : constant$6(+x), pack) : padding;
28886 function radiusLeaf(radius) {
28887 return function(node) {
28888 if (!node.children) {
28889 node.r = Math.max(0, +radius(node) || 0);
28894 function packChildren(padding, k) {
28895 return function(node) {
28896 if (children = node.children) {
28899 n = children.length,
28900 r = padding(node) * k || 0,
28903 if (r) for (i = 0; i < n; ++i) children[i].r += r;
28904 e = packEnclose(children);
28905 if (r) for (i = 0; i < n; ++i) children[i].r -= r;
28911 function translateChild(k) {
28912 return function(node) {
28913 var parent = node.parent;
28916 node.x = parent.x + k * node.x;
28917 node.y = parent.y + k * node.y;
28922 var roundNode = function(node) {
28923 node.x0 = Math.round(node.x0);
28924 node.y0 = Math.round(node.y0);
28925 node.x1 = Math.round(node.x1);
28926 node.y1 = Math.round(node.y1);
28929 var treemapDice = function(parent, x0, y0, x1, y1) {
28930 var nodes = parent.children,
28934 k = parent.value && (x1 - x0) / parent.value;
28937 node = nodes[i], node.y0 = y0, node.y1 = y1;
28938 node.x0 = x0, node.x1 = x0 += node.value * k;
28942 var partition = function() {
28948 function partition(root) {
28949 var n = root.height + 1;
28954 root.eachBefore(positionNode(dy, n));
28955 if (round) root.eachBefore(roundNode);
28959 function positionNode(dy, n) {
28960 return function(node) {
28961 if (node.children) {
28962 treemapDice(node, node.x0, dy * (node.depth + 1) / n, node.x1, dy * (node.depth + 2) / n);
28966 x1 = node.x1 - padding,
28967 y1 = node.y1 - padding;
28968 if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
28969 if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
28977 partition.round = function(x) {
28978 return arguments.length ? (round = !!x, partition) : round;
28981 partition.size = function(x) {
28982 return arguments.length ? (dx = +x[0], dy = +x[1], partition) : [dx, dy];
28985 partition.padding = function(x) {
28986 return arguments.length ? (padding = +x, partition) : padding;
28992 var keyPrefix$1 = "$";
28993 var preroot = {depth: -1};
28994 var ambiguous = {};
28996 function defaultId(d) {
29000 function defaultParentId(d) {
29004 var stratify = function() {
29005 var id = defaultId,
29006 parentId = defaultParentId;
29008 function stratify(data) {
29015 nodes = new Array(n),
29020 for (i = 0; i < n; ++i) {
29021 d = data[i], node = nodes[i] = new Node(d);
29022 if ((nodeId = id(d, i, data)) != null && (nodeId += "")) {
29023 nodeKey = keyPrefix$1 + (node.id = nodeId);
29024 nodeByKey[nodeKey] = nodeKey in nodeByKey ? ambiguous : node;
29028 for (i = 0; i < n; ++i) {
29029 node = nodes[i], nodeId = parentId(data[i], i, data);
29030 if (nodeId == null || !(nodeId += "")) {
29031 if (root) throw new Error("multiple roots");
29034 parent = nodeByKey[keyPrefix$1 + nodeId];
29035 if (!parent) throw new Error("missing: " + nodeId);
29036 if (parent === ambiguous) throw new Error("ambiguous: " + nodeId);
29037 if (parent.children) parent.children.push(node);
29038 else parent.children = [node];
29039 node.parent = parent;
29043 if (!root) throw new Error("no root");
29044 root.parent = preroot;
29045 root.eachBefore(function(node) { node.depth = node.parent.depth + 1; --n; }).eachBefore(computeHeight);
29046 root.parent = null;
29047 if (n > 0) throw new Error("cycle");
29052 stratify.id = function(x) {
29053 return arguments.length ? (id = required(x), stratify) : id;
29056 stratify.parentId = function(x) {
29057 return arguments.length ? (parentId = required(x), stratify) : parentId;
29063 function defaultSeparation$1(a, b) {
29064 return a.parent === b.parent ? 1 : 2;
29067 // function radialSeparation(a, b) {
29068 // return (a.parent === b.parent ? 1 : 2) / a.depth;
29071 // This function is used to traverse the left contour of a subtree (or
29072 // subforest). It returns the successor of v on this contour. This successor is
29073 // either given by the leftmost child of v or by the thread of v. The function
29074 // returns null if and only if v is on the highest level of its subtree.
29075 function nextLeft(v) {
29076 var children = v.children;
29077 return children ? children[0] : v.t;
29080 // This function works analogously to nextLeft.
29081 function nextRight(v) {
29082 var children = v.children;
29083 return children ? children[children.length - 1] : v.t;
29086 // Shifts the current subtree rooted at w+. This is done by increasing
29087 // prelim(w+) and mod(w+) by shift.
29088 function moveSubtree(wm, wp, shift) {
29089 var change = shift / (wp.i - wm.i);
29097 // All other shifts, applied to the smaller subtrees between w- and w+, are
29098 // performed by this function. To prepare the shifts, we have to adjust
29099 // change(w+), shift(w+), and change(w-).
29100 function executeShifts(v) {
29103 children = v.children,
29104 i = children.length,
29110 shift += w.s + (change += w.c);
29114 // If vi-’s ancestor is a sibling of v, returns vi-’s ancestor. Otherwise,
29115 // returns the specified (default) ancestor.
29116 function nextAncestor(vim, v, ancestor) {
29117 return vim.a.parent === v.parent ? vim.a : ancestor;
29120 function TreeNode(node, i) {
29122 this.parent = null;
29123 this.children = null;
29124 this.A = null; // default ancestor
29125 this.a = this; // ancestor
29126 this.z = 0; // prelim
29128 this.c = 0; // change
29129 this.s = 0; // shift
29130 this.t = null; // thread
29131 this.i = i; // number
29134 TreeNode.prototype = Object.create(Node.prototype);
29136 function treeRoot(root) {
29137 var tree = new TreeNode(root, 0),
29145 while (node = nodes.pop()) {
29146 if (children = node._.children) {
29147 node.children = new Array(n = children.length);
29148 for (i = n - 1; i >= 0; --i) {
29149 nodes.push(child = node.children[i] = new TreeNode(children[i], i));
29150 child.parent = node;
29155 (tree.parent = new TreeNode(null, 0)).children = [tree];
29159 // Node-link tree diagram using the Reingold-Tilford "tidy" algorithm
29160 var tree = function() {
29161 var separation = defaultSeparation$1,
29166 function tree(root) {
29167 var t = treeRoot(root);
29169 // Compute the layout using Buchheim et al.’s algorithm.
29170 t.eachAfter(firstWalk), t.parent.m = -t.z;
29171 t.eachBefore(secondWalk);
29173 // If a fixed node size is specified, scale x and y.
29174 if (nodeSize) root.eachBefore(sizeNode);
29176 // If a fixed tree size is specified, scale x and y based on the extent.
29177 // Compute the left-most, right-most, and depth-most nodes for extents.
29182 root.eachBefore(function(node) {
29183 if (node.x < left.x) left = node;
29184 if (node.x > right.x) right = node;
29185 if (node.depth > bottom.depth) bottom = node;
29187 var s = left === right ? 1 : separation(left, right) / 2,
29189 kx = dx / (right.x + s + tx),
29190 ky = dy / (bottom.depth || 1);
29191 root.eachBefore(function(node) {
29192 node.x = (node.x + tx) * kx;
29193 node.y = node.depth * ky;
29200 // Computes a preliminary x-coordinate for v. Before that, FIRST WALK is
29201 // applied recursively to the children of v, as well as the function
29202 // APPORTION. After spacing out the children by calling EXECUTE SHIFTS, the
29203 // node v is placed to the midpoint of its outermost children.
29204 function firstWalk(v) {
29205 var children = v.children,
29206 siblings = v.parent.children,
29207 w = v.i ? siblings[v.i - 1] : null;
29210 var midpoint = (children[0].z + children[children.length - 1].z) / 2;
29212 v.z = w.z + separation(v._, w._);
29213 v.m = v.z - midpoint;
29218 v.z = w.z + separation(v._, w._);
29220 v.parent.A = apportion(v, w, v.parent.A || siblings[0]);
29223 // Computes all real x-coordinates by summing up the modifiers recursively.
29224 function secondWalk(v) {
29225 v._.x = v.z + v.parent.m;
29229 // The core of the algorithm. Here, a new subtree is combined with the
29230 // previous subtrees. Threads are used to traverse the inside and outside
29231 // contours of the left and right subtree up to the highest common level. The
29232 // vertices used for the traversals are vi+, vi-, vo-, and vo+, where the
29233 // superscript o means outside and i means inside, the subscript - means left
29234 // subtree and + means right subtree. For summing up the modifiers along the
29235 // contour, we use respective variables si+, si-, so-, and so+. Whenever two
29236 // nodes of the inside contours conflict, we compute the left one of the
29237 // greatest uncommon ancestors using the function ANCESTOR and call MOVE
29238 // SUBTREE to shift the subtree and prepare the shifts of smaller subtrees.
29239 // Finally, we add a new thread (if necessary).
29240 function apportion(v, w, ancestor) {
29245 vom = vip.parent.children[0],
29251 while (vim = nextRight(vim), vip = nextLeft(vip), vim && vip) {
29252 vom = nextLeft(vom);
29253 vop = nextRight(vop);
29255 shift = vim.z + sim - vip.z - sip + separation(vim._, vip._);
29257 moveSubtree(nextAncestor(vim, v, ancestor), v, shift);
29266 if (vim && !nextRight(vop)) {
29268 vop.m += sim - sop;
29270 if (vip && !nextLeft(vom)) {
29272 vom.m += sip - som;
29279 function sizeNode(node) {
29281 node.y = node.depth * dy;
29284 tree.separation = function(x) {
29285 return arguments.length ? (separation = x, tree) : separation;
29288 tree.size = function(x) {
29289 return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], tree) : (nodeSize ? null : [dx, dy]);
29292 tree.nodeSize = function(x) {
29293 return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], tree) : (nodeSize ? [dx, dy] : null);
29299 var treemapSlice = function(parent, x0, y0, x1, y1) {
29300 var nodes = parent.children,
29304 k = parent.value && (y1 - y0) / parent.value;
29307 node = nodes[i], node.x0 = x0, node.x1 = x1;
29308 node.y0 = y0, node.y1 = y0 += node.value * k;
29312 var phi = (1 + Math.sqrt(5)) / 2;
29314 function squarifyRatio(ratio, parent, x0, y0, x1, y1) {
29316 nodes = parent.children,
29323 value = parent.value,
29333 dx = x1 - x0, dy = y1 - y0;
29334 minValue = maxValue = sumValue = nodes[i0].value;
29335 alpha = Math.max(dy / dx, dx / dy) / (value * ratio);
29336 beta = sumValue * sumValue * alpha;
29337 minRatio = Math.max(maxValue / beta, beta / minValue);
29339 // Keep adding nodes while the aspect ratio maintains or improves.
29340 for (i1 = i0 + 1; i1 < n; ++i1) {
29341 sumValue += nodeValue = nodes[i1].value;
29342 if (nodeValue < minValue) minValue = nodeValue;
29343 if (nodeValue > maxValue) maxValue = nodeValue;
29344 beta = sumValue * sumValue * alpha;
29345 newRatio = Math.max(maxValue / beta, beta / minValue);
29346 if (newRatio > minRatio) { sumValue -= nodeValue; break; }
29347 minRatio = newRatio;
29350 // Position and record the row orientation.
29351 rows.push(row = {value: sumValue, dice: dx < dy, children: nodes.slice(i0, i1)});
29352 if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1);
29353 else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1);
29354 value -= sumValue, i0 = i1;
29360 var squarify = (function custom(ratio) {
29362 function squarify(parent, x0, y0, x1, y1) {
29363 squarifyRatio(ratio, parent, x0, y0, x1, y1);
29366 squarify.ratio = function(x) {
29367 return custom((x = +x) > 1 ? x : 1);
29373 var index$3 = function() {
29374 var tile = squarify,
29378 paddingStack = [0],
29379 paddingInner = constantZero,
29380 paddingTop = constantZero,
29381 paddingRight = constantZero,
29382 paddingBottom = constantZero,
29383 paddingLeft = constantZero;
29385 function treemap(root) {
29390 root.eachBefore(positionNode);
29391 paddingStack = [0];
29392 if (round) root.eachBefore(roundNode);
29396 function positionNode(node) {
29397 var p = paddingStack[node.depth],
29402 if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
29403 if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
29408 if (node.children) {
29409 p = paddingStack[node.depth + 1] = paddingInner(node) / 2;
29410 x0 += paddingLeft(node) - p;
29411 y0 += paddingTop(node) - p;
29412 x1 -= paddingRight(node) - p;
29413 y1 -= paddingBottom(node) - p;
29414 if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
29415 if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
29416 tile(node, x0, y0, x1, y1);
29420 treemap.round = function(x) {
29421 return arguments.length ? (round = !!x, treemap) : round;
29424 treemap.size = function(x) {
29425 return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy];
29428 treemap.tile = function(x) {
29429 return arguments.length ? (tile = required(x), treemap) : tile;
29432 treemap.padding = function(x) {
29433 return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner();
29436 treemap.paddingInner = function(x) {
29437 return arguments.length ? (paddingInner = typeof x === "function" ? x : constant$6(+x), treemap) : paddingInner;
29440 treemap.paddingOuter = function(x) {
29441 return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop();
29444 treemap.paddingTop = function(x) {
29445 return arguments.length ? (paddingTop = typeof x === "function" ? x : constant$6(+x), treemap) : paddingTop;
29448 treemap.paddingRight = function(x) {
29449 return arguments.length ? (paddingRight = typeof x === "function" ? x : constant$6(+x), treemap) : paddingRight;
29452 treemap.paddingBottom = function(x) {
29453 return arguments.length ? (paddingBottom = typeof x === "function" ? x : constant$6(+x), treemap) : paddingBottom;
29456 treemap.paddingLeft = function(x) {
29457 return arguments.length ? (paddingLeft = typeof x === "function" ? x : constant$6(+x), treemap) : paddingLeft;
29463 var binary = function(parent, x0, y0, x1, y1) {
29464 var nodes = parent.children,
29465 i, n = nodes.length,
29466 sum, sums = new Array(n + 1);
29468 for (sums[0] = sum = i = 0; i < n; ++i) {
29469 sums[i + 1] = sum += nodes[i].value;
29472 partition(0, n, parent.value, x0, y0, x1, y1);
29474 function partition(i, j, value, x0, y0, x1, y1) {
29476 var node = nodes[i];
29477 node.x0 = x0, node.y0 = y0;
29478 node.x1 = x1, node.y1 = y1;
29482 var valueOffset = sums[i],
29483 valueTarget = (value / 2) + valueOffset,
29488 var mid = k + hi >>> 1;
29489 if (sums[mid] < valueTarget) k = mid + 1;
29493 var valueLeft = sums[k] - valueOffset,
29494 valueRight = value - valueLeft;
29496 if ((y1 - y0) > (x1 - x0)) {
29497 var yk = (y0 * valueRight + y1 * valueLeft) / value;
29498 partition(i, k, valueLeft, x0, y0, x1, yk);
29499 partition(k, j, valueRight, x0, yk, x1, y1);
29501 var xk = (x0 * valueRight + x1 * valueLeft) / value;
29502 partition(i, k, valueLeft, x0, y0, xk, y1);
29503 partition(k, j, valueRight, xk, y0, x1, y1);
29508 var sliceDice = function(parent, x0, y0, x1, y1) {
29509 (parent.depth & 1 ? treemapSlice : treemapDice)(parent, x0, y0, x1, y1);
29512 var resquarify = (function custom(ratio) {
29514 function resquarify(parent, x0, y0, x1, y1) {
29515 if ((rows = parent._squarify) && (rows.ratio === ratio)) {
29523 value = parent.value;
29526 row = rows[j], nodes = row.children;
29527 for (i = row.value = 0, n = nodes.length; i < n; ++i) row.value += nodes[i].value;
29528 if (row.dice) treemapDice(row, x0, y0, x1, y0 += (y1 - y0) * row.value / value);
29529 else treemapSlice(row, x0, y0, x0 += (x1 - x0) * row.value / value, y1);
29530 value -= row.value;
29533 parent._squarify = rows = squarifyRatio(ratio, parent, x0, y0, x1, y1);
29534 rows.ratio = ratio;
29538 resquarify.ratio = function(x) {
29539 return custom((x = +x) > 1 ? x : 1);
29545 var center$1 = function(x, y) {
29548 if (x == null) x = 0;
29549 if (y == null) y = 0;
29558 for (i = 0; i < n; ++i) {
29559 node = nodes[i], sx += node.x, sy += node.y;
29562 for (sx = sx / n - x, sy = sy / n - y, i = 0; i < n; ++i) {
29563 node = nodes[i], node.x -= sx, node.y -= sy;
29567 force.initialize = function(_) {
29571 force.x = function(_) {
29572 return arguments.length ? (x = +_, force) : x;
29575 force.y = function(_) {
29576 return arguments.length ? (y = +_, force) : y;
29582 var constant$7 = function(x) {
29583 return function() {
29588 var jiggle = function() {
29589 return (Math.random() - 0.5) * 1e-6;
29600 var collide = function(radius) {
29606 if (typeof radius !== "function") radius = constant$7(radius == null ? 1 : +radius);
29609 var i, n = nodes.length,
29617 for (var k = 0; k < iterations; ++k) {
29618 tree = quadtree(nodes, x$1, y$1).visitAfter(prepare);
29619 for (i = 0; i < n; ++i) {
29621 ri = radii[i], ri2 = ri * ri;
29622 xi = node.x + node.vx;
29623 yi = node.y + node.vy;
29628 function apply(quad, x0, y0, x1, y1) {
29629 var data = quad.data, rj = quad.r, r = ri + rj;
29631 if (data.index > i) {
29632 var x = xi - data.x - data.vx,
29633 y = yi - data.y - data.vy,
29636 if (x === 0) x = jiggle(), l += x * x;
29637 if (y === 0) y = jiggle(), l += y * y;
29638 l = (r - (l = Math.sqrt(l))) / l * strength;
29639 node.vx += (x *= l) * (r = (rj *= rj) / (ri2 + rj));
29640 node.vy += (y *= l) * r;
29641 data.vx -= x * (r = 1 - r);
29647 return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r;
29651 function prepare(quad) {
29652 if (quad.data) return quad.r = radii[quad.data.index];
29653 for (var i = quad.r = 0; i < 4; ++i) {
29654 if (quad[i] && quad[i].r > quad.r) {
29655 quad.r = quad[i].r;
29660 function initialize() {
29661 if (!nodes) return;
29662 var i, n = nodes.length;
29663 radii = new Array(n);
29664 for (i = 0; i < n; ++i) radii[i] = +radius(nodes[i], i, nodes);
29667 force.initialize = function(_) {
29672 force.iterations = function(_) {
29673 return arguments.length ? (iterations = +_, force) : iterations;
29676 force.strength = function(_) {
29677 return arguments.length ? (strength = +_, force) : strength;
29680 force.radius = function(_) {
29681 return arguments.length ? (radius = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : radius;
29687 function index$4(d, i) {
29691 function find(nodeById, nodeId) {
29692 var node = nodeById.get(nodeId);
29693 if (!node) throw new Error("missing: " + nodeId);
29697 var link = function(links) {
29699 strength = defaultStrength,
29701 distance = constant$7(30),
29708 if (links == null) links = [];
29710 function defaultStrength(link) {
29711 return 1 / Math.min(count[link.source.index], count[link.target.index]);
29714 function force(alpha) {
29715 for (var k = 0, n = links.length; k < iterations; ++k) {
29716 for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) {
29717 link = links[i], source = link.source, target = link.target;
29718 x = target.x + target.vx - source.x - source.vx || jiggle();
29719 y = target.y + target.vy - source.y - source.vy || jiggle();
29720 l = Math.sqrt(x * x + y * y);
29721 l = (l - distances[i]) / l * alpha * strengths[i];
29723 target.vx -= x * (b = bias[i]);
29724 target.vy -= y * b;
29725 source.vx += x * (b = 1 - b);
29726 source.vy += y * b;
29731 function initialize() {
29732 if (!nodes) return;
29737 nodeById = map$1(nodes, id),
29740 for (i = 0, count = new Array(n); i < n; ++i) {
29744 for (i = 0; i < m; ++i) {
29745 link = links[i], link.index = i;
29746 if (typeof link.source !== "object") link.source = find(nodeById, link.source);
29747 if (typeof link.target !== "object") link.target = find(nodeById, link.target);
29748 ++count[link.source.index], ++count[link.target.index];
29751 for (i = 0, bias = new Array(m); i < m; ++i) {
29752 link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]);
29755 strengths = new Array(m), initializeStrength();
29756 distances = new Array(m), initializeDistance();
29759 function initializeStrength() {
29760 if (!nodes) return;
29762 for (var i = 0, n = links.length; i < n; ++i) {
29763 strengths[i] = +strength(links[i], i, links);
29767 function initializeDistance() {
29768 if (!nodes) return;
29770 for (var i = 0, n = links.length; i < n; ++i) {
29771 distances[i] = +distance(links[i], i, links);
29775 force.initialize = function(_) {
29780 force.links = function(_) {
29781 return arguments.length ? (links = _, initialize(), force) : links;
29784 force.id = function(_) {
29785 return arguments.length ? (id = _, force) : id;
29788 force.iterations = function(_) {
29789 return arguments.length ? (iterations = +_, force) : iterations;
29792 force.strength = function(_) {
29793 return arguments.length ? (strength = typeof _ === "function" ? _ : constant$7(+_), initializeStrength(), force) : strength;
29796 force.distance = function(_) {
29797 return arguments.length ? (distance = typeof _ === "function" ? _ : constant$7(+_), initializeDistance(), force) : distance;
29811 var initialRadius = 10;
29812 var initialAngle = Math.PI * (3 - Math.sqrt(5));
29814 var simulation = function(nodes) {
29818 alphaDecay = 1 - Math.pow(alphaMin, 1 / 300),
29820 velocityDecay = 0.6,
29822 stepper = timer(step),
29823 event = dispatch("tick", "end");
29825 if (nodes == null) nodes = [];
29829 event.call("tick", simulation);
29830 if (alpha < alphaMin) {
29832 event.call("end", simulation);
29837 var i, n = nodes.length, node;
29839 alpha += (alphaTarget - alpha) * alphaDecay;
29841 forces.each(function(force) {
29845 for (i = 0; i < n; ++i) {
29847 if (node.fx == null) node.x += node.vx *= velocityDecay;
29848 else node.x = node.fx, node.vx = 0;
29849 if (node.fy == null) node.y += node.vy *= velocityDecay;
29850 else node.y = node.fy, node.vy = 0;
29854 function initializeNodes() {
29855 for (var i = 0, n = nodes.length, node; i < n; ++i) {
29856 node = nodes[i], node.index = i;
29857 if (isNaN(node.x) || isNaN(node.y)) {
29858 var radius = initialRadius * Math.sqrt(i), angle = i * initialAngle;
29859 node.x = radius * Math.cos(angle);
29860 node.y = radius * Math.sin(angle);
29862 if (isNaN(node.vx) || isNaN(node.vy)) {
29863 node.vx = node.vy = 0;
29868 function initializeForce(force) {
29869 if (force.initialize) force.initialize(nodes);
29875 return simulation = {
29878 restart: function() {
29879 return stepper.restart(step), simulation;
29883 return stepper.stop(), simulation;
29886 nodes: function(_) {
29887 return arguments.length ? (nodes = _, initializeNodes(), forces.each(initializeForce), simulation) : nodes;
29890 alpha: function(_) {
29891 return arguments.length ? (alpha = +_, simulation) : alpha;
29894 alphaMin: function(_) {
29895 return arguments.length ? (alphaMin = +_, simulation) : alphaMin;
29898 alphaDecay: function(_) {
29899 return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay;
29902 alphaTarget: function(_) {
29903 return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget;
29906 velocityDecay: function(_) {
29907 return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay;
29910 force: function(name, _) {
29911 return arguments.length > 1 ? ((_ == null ? forces.remove(name) : forces.set(name, initializeForce(_))), simulation) : forces.get(name);
29914 find: function(x, y, radius) {
29923 if (radius == null) radius = Infinity;
29924 else radius *= radius;
29926 for (i = 0; i < n; ++i) {
29930 d2 = dx * dx + dy * dy;
29931 if (d2 < radius) closest = node, radius = d2;
29937 on: function(name, _) {
29938 return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name);
29943 var manyBody = function() {
29947 strength = constant$7(-30),
29950 distanceMax2 = Infinity,
29953 function force(_) {
29954 var i, n = nodes.length, tree = quadtree(nodes, x$2, y$2).visitAfter(accumulate);
29955 for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply);
29958 function initialize() {
29959 if (!nodes) return;
29960 var i, n = nodes.length;
29961 strengths = new Array(n);
29962 for (i = 0; i < n; ++i) strengths[i] = +strength(nodes[i], i, nodes);
29965 function accumulate(quad) {
29966 var strength = 0, q, c, x$$1, y$$1, i;
29968 // For internal nodes, accumulate forces from child quadrants.
29970 for (x$$1 = y$$1 = i = 0; i < 4; ++i) {
29971 if ((q = quad[i]) && (c = q.value)) {
29972 strength += c, x$$1 += c * q.x, y$$1 += c * q.y;
29975 quad.x = x$$1 / strength;
29976 quad.y = y$$1 / strength;
29979 // For leaf nodes, accumulate forces from coincident quadrants.
29984 do strength += strengths[q.data.index];
29985 while (q = q.next);
29988 quad.value = strength;
29991 function apply(quad, x1, _, x2) {
29992 if (!quad.value) return true;
29994 var x$$1 = quad.x - node.x,
29995 y$$1 = quad.y - node.y,
29997 l = x$$1 * x$$1 + y$$1 * y$$1;
29999 // Apply the Barnes-Hut approximation if possible.
30000 // Limit forces for very close nodes; randomize direction if coincident.
30001 if (w * w / theta2 < l) {
30002 if (l < distanceMax2) {
30003 if (x$$1 === 0) x$$1 = jiggle(), l += x$$1 * x$$1;
30004 if (y$$1 === 0) y$$1 = jiggle(), l += y$$1 * y$$1;
30005 if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
30006 node.vx += x$$1 * quad.value * alpha / l;
30007 node.vy += y$$1 * quad.value * alpha / l;
30012 // Otherwise, process points directly.
30013 else if (quad.length || l >= distanceMax2) return;
30015 // Limit forces for very close nodes; randomize direction if coincident.
30016 if (quad.data !== node || quad.next) {
30017 if (x$$1 === 0) x$$1 = jiggle(), l += x$$1 * x$$1;
30018 if (y$$1 === 0) y$$1 = jiggle(), l += y$$1 * y$$1;
30019 if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
30022 do if (quad.data !== node) {
30023 w = strengths[quad.data.index] * alpha / l;
30024 node.vx += x$$1 * w;
30025 node.vy += y$$1 * w;
30026 } while (quad = quad.next);
30029 force.initialize = function(_) {
30034 force.strength = function(_) {
30035 return arguments.length ? (strength = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : strength;
30038 force.distanceMin = function(_) {
30039 return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2);
30042 force.distanceMax = function(_) {
30043 return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2);
30046 force.theta = function(_) {
30047 return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2);
30053 var x$3 = function(x) {
30054 var strength = constant$7(0.1),
30059 if (typeof x !== "function") x = constant$7(x == null ? 0 : +x);
30061 function force(alpha) {
30062 for (var i = 0, n = nodes.length, node; i < n; ++i) {
30063 node = nodes[i], node.vx += (xz[i] - node.x) * strengths[i] * alpha;
30067 function initialize() {
30068 if (!nodes) return;
30069 var i, n = nodes.length;
30070 strengths = new Array(n);
30072 for (i = 0; i < n; ++i) {
30073 strengths[i] = isNaN(xz[i] = +x(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
30077 force.initialize = function(_) {
30082 force.strength = function(_) {
30083 return arguments.length ? (strength = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : strength;
30086 force.x = function(_) {
30087 return arguments.length ? (x = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : x;
30093 var y$3 = function(y) {
30094 var strength = constant$7(0.1),
30099 if (typeof y !== "function") y = constant$7(y == null ? 0 : +y);
30101 function force(alpha) {
30102 for (var i = 0, n = nodes.length, node; i < n; ++i) {
30103 node = nodes[i], node.vy += (yz[i] - node.y) * strengths[i] * alpha;
30107 function initialize() {
30108 if (!nodes) return;
30109 var i, n = nodes.length;
30110 strengths = new Array(n);
30112 for (i = 0; i < n; ++i) {
30113 strengths[i] = isNaN(yz[i] = +y(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
30117 force.initialize = function(_) {
30122 force.strength = function(_) {
30123 return arguments.length ? (strength = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : strength;
30126 force.y = function(_) {
30127 return arguments.length ? (y = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : y;
30133 function nopropagation() {
30134 event.stopImmediatePropagation();
30137 var noevent = function() {
30138 event.preventDefault();
30139 event.stopImmediatePropagation();
30142 var dragDisable = function(view) {
30143 var root = view.document.documentElement,
30144 selection$$1 = select(view).on("dragstart.drag", noevent, true);
30145 if ("onselectstart" in root) {
30146 selection$$1.on("selectstart.drag", noevent, true);
30148 root.__noselect = root.style.MozUserSelect;
30149 root.style.MozUserSelect = "none";
30153 function yesdrag(view, noclick) {
30154 var root = view.document.documentElement,
30155 selection$$1 = select(view).on("dragstart.drag", null);
30157 selection$$1.on("click.drag", noevent, true);
30158 setTimeout(function() { selection$$1.on("click.drag", null); }, 0);
30160 if ("onselectstart" in root) {
30161 selection$$1.on("selectstart.drag", null);
30163 root.style.MozUserSelect = root.__noselect;
30164 delete root.__noselect;
30168 var constant$8 = function(x) {
30169 return function() {
30174 function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch) {
30175 this.target = target;
30177 this.subject = subject;
30178 this.identifier = id;
30179 this.active = active;
30187 DragEvent.prototype.on = function() {
30188 var value = this._.on.apply(this._, arguments);
30189 return value === this._ ? this : value;
30192 // Ignore right-click, since that should open the context menu.
30193 function defaultFilter() {
30194 return !event.button;
30197 function defaultContainer() {
30198 return this.parentNode;
30201 function defaultSubject(d) {
30202 return d == null ? {x: event.x, y: event.y} : d;
30205 var drag = function() {
30206 var filter = defaultFilter,
30207 container = defaultContainer,
30208 subject = defaultSubject,
30210 listeners = dispatch("start", "drag", "end"),
30215 function drag(selection$$1) {
30217 .on("mousedown.drag", mousedowned)
30218 .on("touchstart.drag", touchstarted)
30219 .on("touchmove.drag", touchmoved)
30220 .on("touchend.drag touchcancel.drag", touchended)
30221 .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
30224 function mousedowned() {
30225 if (touchending || !filter.apply(this, arguments)) return;
30226 var gesture = beforestart("mouse", container.apply(this, arguments), mouse, this, arguments);
30227 if (!gesture) return;
30228 select(event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true);
30229 dragDisable(event.view);
30231 mousemoving = false;
30235 function mousemoved() {
30237 mousemoving = true;
30238 gestures.mouse("drag");
30241 function mouseupped() {
30242 select(event.view).on("mousemove.drag mouseup.drag", null);
30243 yesdrag(event.view, mousemoving);
30245 gestures.mouse("end");
30248 function touchstarted() {
30249 if (!filter.apply(this, arguments)) return;
30250 var touches$$1 = event.changedTouches,
30251 c = container.apply(this, arguments),
30252 n = touches$$1.length, i, gesture;
30254 for (i = 0; i < n; ++i) {
30255 if (gesture = beforestart(touches$$1[i].identifier, c, touch, this, arguments)) {
30262 function touchmoved() {
30263 var touches$$1 = event.changedTouches,
30264 n = touches$$1.length, i, gesture;
30266 for (i = 0; i < n; ++i) {
30267 if (gesture = gestures[touches$$1[i].identifier]) {
30274 function touchended() {
30275 var touches$$1 = event.changedTouches,
30276 n = touches$$1.length, i, gesture;
30278 if (touchending) clearTimeout(touchending);
30279 touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
30280 for (i = 0; i < n; ++i) {
30281 if (gesture = gestures[touches$$1[i].identifier]) {
30288 function beforestart(id, container, point, that, args) {
30289 var p = point(container, id), s, dx, dy,
30290 sublisteners = listeners.copy();
30292 if (!customEvent(new DragEvent(drag, "beforestart", s, id, active, p[0], p[1], 0, 0, sublisteners), function() {
30293 if ((event.subject = s = subject.apply(that, args)) == null) return false;
30294 dx = s.x - p[0] || 0;
30295 dy = s.y - p[1] || 0;
30299 return function gesture(type) {
30302 case "start": gestures[id] = gesture, n = active++; break;
30303 case "end": delete gestures[id], --active; // nobreak
30304 case "drag": p = point(container, id), n = active; break;
30306 customEvent(new DragEvent(drag, type, s, id, n, p[0] + dx, p[1] + dy, p[0] - p0[0], p[1] - p0[1], sublisteners), sublisteners.apply, sublisteners, [type, that, args]);
30310 drag.filter = function(_) {
30311 return arguments.length ? (filter = typeof _ === "function" ? _ : constant$8(!!_), drag) : filter;
30314 drag.container = function(_) {
30315 return arguments.length ? (container = typeof _ === "function" ? _ : constant$8(_), drag) : container;
30318 drag.subject = function(_) {
30319 return arguments.length ? (subject = typeof _ === "function" ? _ : constant$8(_), drag) : subject;
30322 drag.on = function() {
30323 var value = listeners.on.apply(listeners, arguments);
30324 return value === listeners ? drag : value;
30330 var constant$9 = function(x) {
30331 return function() {
30344 function RedBlackTree() {
30345 this._ = null; // root node
30348 function RedBlackNode(node) {
30349 node.U = // parent node
30350 node.C = // color - true for red, false for black
30351 node.L = // left node
30352 node.R = // right node
30353 node.P = // previous node
30354 node.N = null; // next node
30357 RedBlackTree.prototype = {
30358 constructor: RedBlackTree,
30360 insert: function(after, node) {
30361 var parent, grandpa, uncle;
30366 if (after.N) after.N.P = node;
30370 while (after.L) after = after.L;
30376 } else if (this._) {
30377 after = RedBlackFirst(this._);
30380 after.P = after.L = node;
30383 node.P = node.N = null;
30387 node.L = node.R = null;
30392 while (parent && parent.C) {
30393 grandpa = parent.U;
30394 if (parent === grandpa.L) {
30396 if (uncle && uncle.C) {
30397 parent.C = uncle.C = false;
30401 if (after === parent.R) {
30402 RedBlackRotateLeft(this, parent);
30408 RedBlackRotateRight(this, grandpa);
30412 if (uncle && uncle.C) {
30413 parent.C = uncle.C = false;
30417 if (after === parent.L) {
30418 RedBlackRotateRight(this, parent);
30424 RedBlackRotateLeft(this, grandpa);
30432 remove: function(node) {
30433 if (node.N) node.N.P = node.P;
30434 if (node.P) node.P.N = node.N;
30435 node.N = node.P = null;
30437 var parent = node.U,
30444 if (!left) next = right;
30445 else if (!right) next = left;
30446 else next = RedBlackFirst(right);
30449 if (parent.L === node) parent.L = next;
30450 else parent.R = next;
30455 if (left && right) {
30460 if (next !== right) {
30477 if (node) node.U = parent;
30479 if (node && node.C) { node.C = false; return; }
30482 if (node === this._) break;
30483 if (node === parent.L) {
30484 sibling = parent.R;
30488 RedBlackRotateLeft(this, parent);
30489 sibling = parent.R;
30491 if ((sibling.L && sibling.L.C)
30492 || (sibling.R && sibling.R.C)) {
30493 if (!sibling.R || !sibling.R.C) {
30494 sibling.L.C = false;
30496 RedBlackRotateRight(this, sibling);
30497 sibling = parent.R;
30499 sibling.C = parent.C;
30500 parent.C = sibling.R.C = false;
30501 RedBlackRotateLeft(this, parent);
30506 sibling = parent.L;
30510 RedBlackRotateRight(this, parent);
30511 sibling = parent.L;
30513 if ((sibling.L && sibling.L.C)
30514 || (sibling.R && sibling.R.C)) {
30515 if (!sibling.L || !sibling.L.C) {
30516 sibling.R.C = false;
30518 RedBlackRotateLeft(this, sibling);
30519 sibling = parent.L;
30521 sibling.C = parent.C;
30522 parent.C = sibling.L.C = false;
30523 RedBlackRotateRight(this, parent);
30533 if (node) node.C = false;
30537 function RedBlackRotateLeft(tree, node) {
30543 if (parent.L === p) parent.L = q;
30552 if (p.R) p.R.U = p;
30556 function RedBlackRotateRight(tree, node) {
30562 if (parent.L === p) parent.L = q;
30571 if (p.L) p.L.U = p;
30575 function RedBlackFirst(node) {
30576 while (node.L) node = node.L;
30580 function createEdge(left, right, v0, v1) {
30581 var edge = [null, null],
30582 index = edges.push(edge) - 1;
30584 edge.right = right;
30585 if (v0) setEdgeEnd(edge, left, right, v0);
30586 if (v1) setEdgeEnd(edge, right, left, v1);
30587 cells[left.index].halfedges.push(index);
30588 cells[right.index].halfedges.push(index);
30592 function createBorderEdge(left, v0, v1) {
30593 var edge = [v0, v1];
30598 function setEdgeEnd(edge, left, right, vertex) {
30599 if (!edge[0] && !edge[1]) {
30602 edge.right = right;
30603 } else if (edge.left === right) {
30610 // Liang–Barsky line clipping.
30611 function clipEdge(edge, x0, y0, x1, y1) {
30625 if (!dx && r > 0) return;
30628 if (r < t0) return;
30629 if (r < t1) t1 = r;
30630 } else if (dx > 0) {
30631 if (r > t1) return;
30632 if (r > t0) t0 = r;
30636 if (!dx && r < 0) return;
30639 if (r > t1) return;
30640 if (r > t0) t0 = r;
30641 } else if (dx > 0) {
30642 if (r < t0) return;
30643 if (r < t1) t1 = r;
30647 if (!dy && r > 0) return;
30650 if (r < t0) return;
30651 if (r < t1) t1 = r;
30652 } else if (dy > 0) {
30653 if (r > t1) return;
30654 if (r > t0) t0 = r;
30658 if (!dy && r < 0) return;
30661 if (r > t1) return;
30662 if (r > t0) t0 = r;
30663 } else if (dy > 0) {
30664 if (r < t0) return;
30665 if (r < t1) t1 = r;
30668 if (!(t0 > 0) && !(t1 < 1)) return true; // TODO Better check?
30670 if (t0 > 0) edge[0] = [ax + t0 * dx, ay + t0 * dy];
30671 if (t1 < 1) edge[1] = [ax + t1 * dx, ay + t1 * dy];
30675 function connectEdge(edge, x0, y0, x1, y1) {
30677 if (v1) return true;
30681 right = edge.right,
30686 fx = (lx + rx) / 2,
30687 fy = (ly + ry) / 2,
30692 if (fx < x0 || fx >= x1) return;
30694 if (!v0) v0 = [fx, y0];
30695 else if (v0[1] >= y1) return;
30698 if (!v0) v0 = [fx, y1];
30699 else if (v0[1] < y0) return;
30703 fm = (lx - rx) / (ry - ly);
30705 if (fm < -1 || fm > 1) {
30707 if (!v0) v0 = [(y0 - fb) / fm, y0];
30708 else if (v0[1] >= y1) return;
30709 v1 = [(y1 - fb) / fm, y1];
30711 if (!v0) v0 = [(y1 - fb) / fm, y1];
30712 else if (v0[1] < y0) return;
30713 v1 = [(y0 - fb) / fm, y0];
30717 if (!v0) v0 = [x0, fm * x0 + fb];
30718 else if (v0[0] >= x1) return;
30719 v1 = [x1, fm * x1 + fb];
30721 if (!v0) v0 = [x1, fm * x1 + fb];
30722 else if (v0[0] < x0) return;
30723 v1 = [x0, fm * x0 + fb];
30733 function clipEdges(x0, y0, x1, y1) {
30734 var i = edges.length,
30738 if (!connectEdge(edge = edges[i], x0, y0, x1, y1)
30739 || !clipEdge(edge, x0, y0, x1, y1)
30740 || !(Math.abs(edge[0][0] - edge[1][0]) > epsilon$3
30741 || Math.abs(edge[0][1] - edge[1][1]) > epsilon$3)) {
30747 function createCell(site) {
30748 return cells[site.index] = {
30754 function cellHalfedgeAngle(cell, edge) {
30755 var site = cell.site,
30758 if (site === vb) vb = va, va = site;
30759 if (vb) return Math.atan2(vb[1] - va[1], vb[0] - va[0]);
30760 if (site === va) va = edge[1], vb = edge[0];
30761 else va = edge[0], vb = edge[1];
30762 return Math.atan2(va[0] - vb[0], vb[1] - va[1]);
30765 function cellHalfedgeStart(cell, edge) {
30766 return edge[+(edge.left !== cell.site)];
30769 function cellHalfedgeEnd(cell, edge) {
30770 return edge[+(edge.left === cell.site)];
30773 function sortCellHalfedges() {
30774 for (var i = 0, n = cells.length, cell, halfedges, j, m; i < n; ++i) {
30775 if ((cell = cells[i]) && (m = (halfedges = cell.halfedges).length)) {
30776 var index = new Array(m),
30777 array = new Array(m);
30778 for (j = 0; j < m; ++j) index[j] = j, array[j] = cellHalfedgeAngle(cell, edges[halfedges[j]]);
30779 index.sort(function(i, j) { return array[j] - array[i]; });
30780 for (j = 0; j < m; ++j) array[j] = halfedges[index[j]];
30781 for (j = 0; j < m; ++j) halfedges[j] = array[j];
30786 function clipCells(x0, y0, x1, y1) {
30787 var nCells = cells.length,
30802 for (iCell = 0; iCell < nCells; ++iCell) {
30803 if (cell = cells[iCell]) {
30805 halfedges = cell.halfedges;
30806 iHalfedge = halfedges.length;
30808 // Remove any dangling clipped edges.
30809 while (iHalfedge--) {
30810 if (!edges[halfedges[iHalfedge]]) {
30811 halfedges.splice(iHalfedge, 1);
30815 // Insert any border edges as necessary.
30816 iHalfedge = 0, nHalfedges = halfedges.length;
30817 while (iHalfedge < nHalfedges) {
30818 end = cellHalfedgeEnd(cell, edges[halfedges[iHalfedge]]), endX = end[0], endY = end[1];
30819 start = cellHalfedgeStart(cell, edges[halfedges[++iHalfedge % nHalfedges]]), startX = start[0], startY = start[1];
30820 if (Math.abs(endX - startX) > epsilon$3 || Math.abs(endY - startY) > epsilon$3) {
30821 halfedges.splice(iHalfedge, 0, edges.push(createBorderEdge(site, end,
30822 Math.abs(endX - x0) < epsilon$3 && y1 - endY > epsilon$3 ? [x0, Math.abs(startX - x0) < epsilon$3 ? startY : y1]
30823 : Math.abs(endY - y1) < epsilon$3 && x1 - endX > epsilon$3 ? [Math.abs(startY - y1) < epsilon$3 ? startX : x1, y1]
30824 : Math.abs(endX - x1) < epsilon$3 && endY - y0 > epsilon$3 ? [x1, Math.abs(startX - x1) < epsilon$3 ? startY : y0]
30825 : Math.abs(endY - y0) < epsilon$3 && endX - x0 > epsilon$3 ? [Math.abs(startY - y0) < epsilon$3 ? startX : x0, y0]
30831 if (nHalfedges) cover = false;
30835 // If there weren’t any edges, have the closest site cover the extent.
30836 // It doesn’t matter which corner of the extent we measure!
30838 var dx, dy, d2, dc = Infinity;
30840 for (iCell = 0, cover = null; iCell < nCells; ++iCell) {
30841 if (cell = cells[iCell]) {
30845 d2 = dx * dx + dy * dy;
30846 if (d2 < dc) dc = d2, cover = cell;
30851 var v00 = [x0, y0], v01 = [x0, y1], v11 = [x1, y1], v10 = [x1, y0];
30852 cover.halfedges.push(
30853 edges.push(createBorderEdge(site = cover.site, v00, v01)) - 1,
30854 edges.push(createBorderEdge(site, v01, v11)) - 1,
30855 edges.push(createBorderEdge(site, v11, v10)) - 1,
30856 edges.push(createBorderEdge(site, v10, v00)) - 1
30861 // Lastly delete any cells with no edges; these were entirely clipped.
30862 for (iCell = 0; iCell < nCells; ++iCell) {
30863 if (cell = cells[iCell]) {
30864 if (!cell.halfedges.length) {
30865 delete cells[iCell];
30871 var circlePool = [];
30875 function Circle() {
30876 RedBlackNode(this);
30884 function attachCircle(arc) {
30888 if (!lArc || !rArc) return;
30890 var lSite = lArc.site,
30894 if (lSite === rSite) return;
30898 ax = lSite[0] - bx,
30899 ay = lSite[1] - by,
30900 cx = rSite[0] - bx,
30901 cy = rSite[1] - by;
30903 var d = 2 * (ax * cy - ay * cx);
30904 if (d >= -epsilon2$1) return;
30906 var ha = ax * ax + ay * ay,
30907 hc = cx * cx + cy * cy,
30908 x = (cy * ha - ay * hc) / d,
30909 y = (ax * hc - cx * ha) / d;
30911 var circle = circlePool.pop() || new Circle;
30913 circle.site = cSite;
30915 circle.y = (circle.cy = y + by) + Math.sqrt(x * x + y * y); // y bottom
30917 arc.circle = circle;
30923 if (circle.y < node.y || (circle.y === node.y && circle.x <= node.x)) {
30924 if (node.L) node = node.L;
30925 else { before = node.P; break; }
30927 if (node.R) node = node.R;
30928 else { before = node; break; }
30932 circles.insert(before, circle);
30933 if (!before) firstCircle = circle;
30936 function detachCircle(arc) {
30937 var circle = arc.circle;
30939 if (!circle.P) firstCircle = circle.N;
30940 circles.remove(circle);
30941 circlePool.push(circle);
30942 RedBlackNode(circle);
30947 var beachPool = [];
30950 RedBlackNode(this);
30953 this.circle = null;
30956 function createBeach(site) {
30957 var beach = beachPool.pop() || new Beach;
30962 function detachBeach(beach) {
30963 detachCircle(beach);
30964 beaches.remove(beach);
30965 beachPool.push(beach);
30966 RedBlackNode(beach);
30969 function removeBeach(beach) {
30970 var circle = beach.circle,
30974 previous = beach.P,
30976 disappearing = [beach];
30978 detachBeach(beach);
30980 var lArc = previous;
30982 && Math.abs(x - lArc.circle.x) < epsilon$3
30983 && Math.abs(y - lArc.circle.cy) < epsilon$3) {
30985 disappearing.unshift(lArc);
30990 disappearing.unshift(lArc);
30991 detachCircle(lArc);
30995 && Math.abs(x - rArc.circle.x) < epsilon$3
30996 && Math.abs(y - rArc.circle.cy) < epsilon$3) {
30998 disappearing.push(rArc);
31003 disappearing.push(rArc);
31004 detachCircle(rArc);
31006 var nArcs = disappearing.length,
31008 for (iArc = 1; iArc < nArcs; ++iArc) {
31009 rArc = disappearing[iArc];
31010 lArc = disappearing[iArc - 1];
31011 setEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex);
31014 lArc = disappearing[0];
31015 rArc = disappearing[nArcs - 1];
31016 rArc.edge = createEdge(lArc.site, rArc.site, null, vertex);
31018 attachCircle(lArc);
31019 attachCircle(rArc);
31022 function addBeach(site) {
31024 directrix = site[1],
31032 dxl = leftBreakPoint(node, directrix) - x;
31033 if (dxl > epsilon$3) node = node.L; else {
31034 dxr = x - rightBreakPoint(node, directrix);
31035 if (dxr > epsilon$3) {
31042 if (dxl > -epsilon$3) {
31045 } else if (dxr > -epsilon$3) {
31049 lArc = rArc = node;
31057 var newArc = createBeach(site);
31058 beaches.insert(lArc, newArc);
31060 if (!lArc && !rArc) return;
31062 if (lArc === rArc) {
31063 detachCircle(lArc);
31064 rArc = createBeach(lArc.site);
31065 beaches.insert(newArc, rArc);
31066 newArc.edge = rArc.edge = createEdge(lArc.site, newArc.site);
31067 attachCircle(lArc);
31068 attachCircle(rArc);
31072 if (!rArc) { // && lArc
31073 newArc.edge = createEdge(lArc.site, newArc.site);
31077 // else lArc !== rArc
31078 detachCircle(lArc);
31079 detachCircle(rArc);
31081 var lSite = lArc.site,
31087 cx = rSite[0] - ax,
31088 cy = rSite[1] - ay,
31089 d = 2 * (bx * cy - by * cx),
31090 hb = bx * bx + by * by,
31091 hc = cx * cx + cy * cy,
31092 vertex = [(cy * hb - by * hc) / d + ax, (bx * hc - cx * hb) / d + ay];
31094 setEdgeEnd(rArc.edge, lSite, rSite, vertex);
31095 newArc.edge = createEdge(lSite, site, null, vertex);
31096 rArc.edge = createEdge(site, rSite, null, vertex);
31097 attachCircle(lArc);
31098 attachCircle(rArc);
31101 function leftBreakPoint(arc, directrix) {
31102 var site = arc.site,
31105 pby2 = rfocy - directrix;
31107 if (!pby2) return rfocx;
31110 if (!lArc) return -Infinity;
31113 var lfocx = site[0],
31115 plby2 = lfocy - directrix;
31117 if (!plby2) return lfocx;
31119 var hl = lfocx - rfocx,
31120 aby2 = 1 / pby2 - 1 / plby2,
31123 if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx;
31125 return (rfocx + lfocx) / 2;
31128 function rightBreakPoint(arc, directrix) {
31130 if (rArc) return leftBreakPoint(rArc, directrix);
31131 var site = arc.site;
31132 return site[1] === directrix ? site[0] : Infinity;
31135 var epsilon$3 = 1e-6;
31136 var epsilon2$1 = 1e-12;
31142 function triangleArea(a, b, c) {
31143 return (a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]);
31146 function lexicographic(a, b) {
31151 function Diagram(sites, extent) {
31152 var site = sites.sort(lexicographic).pop(),
31158 cells = new Array(sites.length);
31159 beaches = new RedBlackTree;
31160 circles = new RedBlackTree;
31163 circle = firstCircle;
31164 if (site && (!circle || site[1] < circle.y || (site[1] === circle.y && site[0] < circle.x))) {
31165 if (site[0] !== x || site[1] !== y) {
31167 x = site[0], y = site[1];
31169 site = sites.pop();
31170 } else if (circle) {
31171 removeBeach(circle.arc);
31177 sortCellHalfedges();
31180 var x0 = +extent[0][0],
31181 y0 = +extent[0][1],
31182 x1 = +extent[1][0],
31183 y1 = +extent[1][1];
31184 clipEdges(x0, y0, x1, y1);
31185 clipCells(x0, y0, x1, y1);
31188 this.edges = edges;
31189 this.cells = cells;
31197 Diagram.prototype = {
31198 constructor: Diagram,
31200 polygons: function() {
31201 var edges = this.edges;
31203 return this.cells.map(function(cell) {
31204 var polygon = cell.halfedges.map(function(i) { return cellHalfedgeStart(cell, edges[i]); });
31205 polygon.data = cell.site.data;
31210 triangles: function() {
31211 var triangles = [],
31212 edges = this.edges;
31214 this.cells.forEach(function(cell, i) {
31215 var site = cell.site,
31216 halfedges = cell.halfedges,
31218 m = halfedges.length,
31220 e1 = edges[halfedges[m - 1]],
31221 s1 = e1.left === site ? e1.right : e1.left;
31225 e1 = edges[halfedges[j]];
31226 s1 = e1.left === site ? e1.right : e1.left;
31227 if (s0 && s1 && i < s0.index && i < s1.index && triangleArea(site, s0, s1) < 0) {
31228 triangles.push([site.data, s0.data, s1.data]);
31236 links: function() {
31237 return this.edges.filter(function(edge) {
31239 }).map(function(edge) {
31241 source: edge.left.data,
31242 target: edge.right.data
31247 find: function(x, y, radius) {
31249 i0, i1 = that._found || 0,
31250 cell = that.cells[i1] || that.cells[i1 = 0],
31251 dx = x - cell.site[0],
31252 dy = y - cell.site[1],
31253 d2 = dx * dx + dy * dy;
31256 cell = that.cells[i0 = i1], i1 = null;
31257 cell.halfedges.forEach(function(e) {
31258 var edge = that.edges[e], v = edge.left;
31259 if ((v === cell.site || !v) && !(v = edge.right)) return;
31262 v2 = vx * vx + vy * vy;
31263 if (v2 < d2) d2 = v2, i1 = v.index;
31265 } while (i1 !== null);
31269 return radius == null || d2 <= radius * radius ? cell.site : null;
31273 var voronoi = function() {
31278 function voronoi(data) {
31279 return new Diagram(data.map(function(d, i) {
31280 var s = [Math.round(x$$1(d, i, data) / epsilon$3) * epsilon$3, Math.round(y$$1(d, i, data) / epsilon$3) * epsilon$3];
31287 voronoi.polygons = function(data) {
31288 return voronoi(data).polygons();
31291 voronoi.links = function(data) {
31292 return voronoi(data).links();
31295 voronoi.triangles = function(data) {
31296 return voronoi(data).triangles();
31299 voronoi.x = function(_) {
31300 return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$9(+_), voronoi) : x$$1;
31303 voronoi.y = function(_) {
31304 return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$9(+_), voronoi) : y$$1;
31307 voronoi.extent = function(_) {
31308 return arguments.length ? (extent = _ == null ? null : [[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]], voronoi) : extent && [[extent[0][0], extent[0][1]], [extent[1][0], extent[1][1]]];
31311 voronoi.size = function(_) {
31312 return arguments.length ? (extent = _ == null ? null : [[0, 0], [+_[0], +_[1]]], voronoi) : extent && [extent[1][0] - extent[0][0], extent[1][1] - extent[0][1]];
31318 var constant$10 = function(x) {
31319 return function() {
31324 function ZoomEvent(target, type, transform) {
31325 this.target = target;
31327 this.transform = transform;
31330 function Transform(k, x, y) {
31336 Transform.prototype = {
31337 constructor: Transform,
31338 scale: function(k) {
31339 return k === 1 ? this : new Transform(this.k * k, this.x, this.y);
31341 translate: function(x, y) {
31342 return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y);
31344 apply: function(point) {
31345 return [point[0] * this.k + this.x, point[1] * this.k + this.y];
31347 applyX: function(x) {
31348 return x * this.k + this.x;
31350 applyY: function(y) {
31351 return y * this.k + this.y;
31353 invert: function(location) {
31354 return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k];
31356 invertX: function(x) {
31357 return (x - this.x) / this.k;
31359 invertY: function(y) {
31360 return (y - this.y) / this.k;
31362 rescaleX: function(x) {
31363 return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x));
31365 rescaleY: function(y) {
31366 return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y));
31368 toString: function() {
31369 return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")";
31373 var identity$6 = new Transform(1, 0, 0);
31375 transform.prototype = Transform.prototype;
31377 function transform(node) {
31378 return node.__zoom || identity$6;
31381 function nopropagation$1() {
31382 event.stopImmediatePropagation();
31385 var noevent$1 = function() {
31386 event.preventDefault();
31387 event.stopImmediatePropagation();
31390 // Ignore right-click, since that should open the context menu.
31391 function defaultFilter$1() {
31392 return !event.button;
31395 function defaultExtent() {
31396 var e = this, w, h;
31397 if (e instanceof SVGElement) {
31398 e = e.ownerSVGElement || e;
31399 w = e.width.baseVal.value;
31400 h = e.height.baseVal.value;
31403 h = e.clientHeight;
31405 return [[0, 0], [w, h]];
31408 function defaultTransform() {
31409 return this.__zoom || identity$6;
31412 var zoom = function() {
31413 var filter = defaultFilter$1,
31414 extent = defaultExtent,
31423 listeners = dispatch("start", "zoom", "end"),
31429 function zoom(selection$$1) {
31431 .on("wheel.zoom", wheeled)
31432 .on("mousedown.zoom", mousedowned)
31433 .on("dblclick.zoom", dblclicked)
31434 .on("touchstart.zoom", touchstarted)
31435 .on("touchmove.zoom", touchmoved)
31436 .on("touchend.zoom touchcancel.zoom", touchended)
31437 .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)")
31438 .property("__zoom", defaultTransform);
31441 zoom.transform = function(collection, transform) {
31442 var selection$$1 = collection.selection ? collection.selection() : collection;
31443 selection$$1.property("__zoom", defaultTransform);
31444 if (collection !== selection$$1) {
31445 schedule(collection, transform);
31447 selection$$1.interrupt().each(function() {
31448 gesture(this, arguments)
31450 .zoom(null, typeof transform === "function" ? transform.apply(this, arguments) : transform)
31456 zoom.scaleBy = function(selection$$1, k) {
31457 zoom.scaleTo(selection$$1, function() {
31458 var k0 = this.__zoom.k,
31459 k1 = typeof k === "function" ? k.apply(this, arguments) : k;
31464 zoom.scaleTo = function(selection$$1, k) {
31465 zoom.transform(selection$$1, function() {
31466 var e = extent.apply(this, arguments),
31469 p1 = t0.invert(p0),
31470 k1 = typeof k === "function" ? k.apply(this, arguments) : k;
31471 return constrain(translate(scale(t0, k1), p0, p1), e);
31475 zoom.translateBy = function(selection$$1, x, y) {
31476 zoom.transform(selection$$1, function() {
31477 return constrain(this.__zoom.translate(
31478 typeof x === "function" ? x.apply(this, arguments) : x,
31479 typeof y === "function" ? y.apply(this, arguments) : y
31480 ), extent.apply(this, arguments));
31484 function scale(transform, k) {
31485 k = Math.max(k0, Math.min(k1, k));
31486 return k === transform.k ? transform : new Transform(k, transform.x, transform.y);
31489 function translate(transform, p0, p1) {
31490 var x = p0[0] - p1[0] * transform.k, y = p0[1] - p1[1] * transform.k;
31491 return x === transform.x && y === transform.y ? transform : new Transform(transform.k, x, y);
31494 function constrain(transform, extent) {
31495 var dx = Math.min(0, transform.invertX(extent[0][0]) - x0) || Math.max(0, transform.invertX(extent[1][0]) - x1),
31496 dy = Math.min(0, transform.invertY(extent[0][1]) - y0) || Math.max(0, transform.invertY(extent[1][1]) - y1);
31497 return dx || dy ? transform.translate(dx, dy) : transform;
31500 function centroid(extent) {
31501 return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2];
31504 function schedule(transition$$1, transform, center) {
31506 .on("start.zoom", function() { gesture(this, arguments).start(); })
31507 .on("interrupt.zoom end.zoom", function() { gesture(this, arguments).end(); })
31508 .tween("zoom", function() {
31511 g = gesture(that, args),
31512 e = extent.apply(that, args),
31513 p = center || centroid(e),
31514 w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]),
31516 b = typeof transform === "function" ? transform.apply(that, args) : transform,
31517 i = interpolateZoom(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k));
31518 return function(t) {
31519 if (t === 1) t = b; // Avoid rounding error on end.
31520 else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); }
31526 function gesture(that, args) {
31527 for (var i = 0, n = gestures.length, g; i < n; ++i) {
31528 if ((g = gestures[i]).that === that) {
31532 return new Gesture(that, args);
31535 function Gesture(that, args) {
31540 this.extent = extent.apply(that, args);
31543 Gesture.prototype = {
31544 start: function() {
31545 if (++this.active === 1) {
31546 this.index = gestures.push(this) - 1;
31547 this.emit("start");
31551 zoom: function(key, transform) {
31552 if (this.mouse && key !== "mouse") this.mouse[1] = transform.invert(this.mouse[0]);
31553 if (this.touch0 && key !== "touch") this.touch0[1] = transform.invert(this.touch0[0]);
31554 if (this.touch1 && key !== "touch") this.touch1[1] = transform.invert(this.touch1[0]);
31555 this.that.__zoom = transform;
31560 if (--this.active === 0) {
31561 gestures.splice(this.index, 1);
31567 emit: function(type) {
31568 customEvent(new ZoomEvent(zoom, type, this.that.__zoom), listeners.apply, listeners, [type, this.that, this.args]);
31572 function wheeled() {
31573 if (!filter.apply(this, arguments)) return;
31574 var g = gesture(this, arguments),
31576 k = Math.max(k0, Math.min(k1, t.k * Math.pow(2, -event.deltaY * (event.deltaMode ? 120 : 1) / 500))),
31579 // If the mouse is in the same location as before, reuse it.
31580 // If there were recent wheel events, reset the wheel idle timeout.
31582 if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) {
31583 g.mouse[1] = t.invert(g.mouse[0] = p);
31585 clearTimeout(g.wheel);
31588 // If this wheel event won’t trigger a transform change, ignore it.
31589 else if (t.k === k) return;
31591 // Otherwise, capture the mouse point and location at the start.
31593 g.mouse = [p, t.invert(p)];
31599 g.wheel = setTimeout(wheelidled, wheelDelay);
31600 g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent));
31602 function wheelidled() {
31608 function mousedowned() {
31609 if (touchending || !filter.apply(this, arguments)) return;
31610 var g = gesture(this, arguments),
31611 v = select(event.view).on("mousemove.zoom", mousemoved, true).on("mouseup.zoom", mouseupped, true),
31614 dragDisable(event.view);
31616 g.mouse = [p, this.__zoom.invert(p)];
31620 function mousemoved() {
31623 g.zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = mouse(g.that), g.mouse[1]), g.extent));
31626 function mouseupped() {
31627 v.on("mousemove.zoom mouseup.zoom", null);
31628 yesdrag(event.view, g.moved);
31634 function dblclicked() {
31635 if (!filter.apply(this, arguments)) return;
31636 var t0 = this.__zoom,
31638 p1 = t0.invert(p0),
31639 k1 = t0.k * (event.shiftKey ? 0.5 : 2),
31640 t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, arguments));
31643 if (duration > 0) select(this).transition().duration(duration).call(schedule, t1, p0);
31644 else select(this).call(zoom.transform, t1);
31647 function touchstarted() {
31648 if (!filter.apply(this, arguments)) return;
31649 var g = gesture(this, arguments),
31650 touches$$1 = event.changedTouches,
31651 n = touches$$1.length, i, t, p;
31654 for (i = 0; i < n; ++i) {
31655 t = touches$$1[i], p = touch(this, touches$$1, t.identifier);
31656 p = [p, this.__zoom.invert(p), t.identifier];
31657 if (!g.touch0) g.touch0 = p;
31658 else if (!g.touch1) g.touch1 = p;
31660 if (touchstarting) {
31661 touchstarting = clearTimeout(touchstarting);
31662 if (!g.touch1) return g.end(), dblclicked.apply(this, arguments);
31664 if (event.touches.length === n) {
31665 touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay);
31671 function touchmoved() {
31672 var g = gesture(this, arguments),
31673 touches$$1 = event.changedTouches,
31674 n = touches$$1.length, i, t, p, l;
31677 if (touchstarting) touchstarting = clearTimeout(touchstarting);
31678 for (i = 0; i < n; ++i) {
31679 t = touches$$1[i], p = touch(this, touches$$1, t.identifier);
31680 if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p;
31681 else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p;
31685 var p0 = g.touch0[0], l0 = g.touch0[1],
31686 p1 = g.touch1[0], l1 = g.touch1[1],
31687 dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp,
31688 dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl;
31689 t = scale(t, Math.sqrt(dp / dl));
31690 p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2];
31691 l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];
31693 else if (g.touch0) p = g.touch0[0], l = g.touch0[1];
31695 g.zoom("touch", constrain(translate(t, p, l), g.extent));
31698 function touchended() {
31699 var g = gesture(this, arguments),
31700 touches$$1 = event.changedTouches,
31701 n = touches$$1.length, i, t;
31704 if (touchending) clearTimeout(touchending);
31705 touchending = setTimeout(function() { touchending = null; }, touchDelay);
31706 for (i = 0; i < n; ++i) {
31708 if (g.touch0 && g.touch0[2] === t.identifier) delete g.touch0;
31709 else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1;
31711 if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1;
31712 if (!g.touch0) g.end();
31715 zoom.filter = function(_) {
31716 return arguments.length ? (filter = typeof _ === "function" ? _ : constant$10(!!_), zoom) : filter;
31719 zoom.extent = function(_) {
31720 return arguments.length ? (extent = typeof _ === "function" ? _ : constant$10([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent;
31723 zoom.scaleExtent = function(_) {
31724 return arguments.length ? (k0 = +_[0], k1 = +_[1], zoom) : [k0, k1];
31727 zoom.translateExtent = function(_) {
31728 return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], zoom) : [[x0, y0], [x1, y1]];
31731 zoom.duration = function(_) {
31732 return arguments.length ? (duration = +_, zoom) : duration;
31735 zoom.on = function() {
31736 var value = listeners.on.apply(listeners, arguments);
31737 return value === listeners ? zoom : value;
31743 var constant$11 = function(x) {
31744 return function() {
31749 var BrushEvent = function(target, type, selection) {
31750 this.target = target;
31752 this.selection = selection;
31755 function nopropagation$2() {
31756 event.stopImmediatePropagation();
31759 var noevent$2 = function() {
31760 event.preventDefault();
31761 event.stopImmediatePropagation();
31764 var MODE_DRAG = {name: "drag"};
31765 var MODE_SPACE = {name: "space"};
31766 var MODE_HANDLE = {name: "handle"};
31767 var MODE_CENTER = {name: "center"};
31771 handles: ["e", "w"].map(type$3),
31772 input: function(x, e) { return x && [[x[0], e[0][1]], [x[1], e[1][1]]]; },
31773 output: function(xy) { return xy && [xy[0][0], xy[1][0]]; }
31778 handles: ["n", "s"].map(type$3),
31779 input: function(y, e) { return y && [[e[0][0], y[0]], [e[1][0], y[1]]]; },
31780 output: function(xy) { return xy && [xy[0][1], xy[1][1]]; }
31785 handles: ["n", "e", "s", "w", "nw", "ne", "se", "sw"].map(type$3),
31786 input: function(xy) { return xy; },
31787 output: function(xy) { return xy; }
31791 overlay: "crosshair",
31847 function type$3(t) {
31851 // Ignore right-click, since that should open the context menu.
31852 function defaultFilter$2() {
31853 return !event.button;
31856 function defaultExtent$1() {
31857 var svg = this.ownerSVGElement || this;
31858 return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];
31861 // Like d3.local, but with the name “__brush” rather than auto-generated.
31862 function local$1(node) {
31863 while (!node.__brush) if (!(node = node.parentNode)) return;
31864 return node.__brush;
31867 function empty$1(extent) {
31868 return extent[0][0] === extent[1][0]
31869 || extent[0][1] === extent[1][1];
31872 function brushSelection(node) {
31873 var state = node.__brush;
31874 return state ? state.dim.output(state.selection) : null;
31877 function brushX() {
31881 function brushY() {
31885 var brush = function() {
31886 return brush$1(XY);
31889 function brush$1(dim) {
31890 var extent = defaultExtent$1,
31891 filter = defaultFilter$2,
31892 listeners = dispatch(brush, "start", "brush", "end"),
31896 function brush(group) {
31897 var overlay = group
31898 .property("__brush", initialize)
31899 .selectAll(".overlay")
31900 .data([type$3("overlay")]);
31902 overlay.enter().append("rect")
31903 .attr("class", "overlay")
31904 .attr("pointer-events", "all")
31905 .attr("cursor", cursors.overlay)
31908 var extent = local$1(this).extent;
31910 .attr("x", extent[0][0])
31911 .attr("y", extent[0][1])
31912 .attr("width", extent[1][0] - extent[0][0])
31913 .attr("height", extent[1][1] - extent[0][1]);
31916 group.selectAll(".selection")
31917 .data([type$3("selection")])
31918 .enter().append("rect")
31919 .attr("class", "selection")
31920 .attr("cursor", cursors.selection)
31921 .attr("fill", "#777")
31922 .attr("fill-opacity", 0.3)
31923 .attr("stroke", "#fff")
31924 .attr("shape-rendering", "crispEdges");
31926 var handle = group.selectAll(".handle")
31927 .data(dim.handles, function(d) { return d.type; });
31929 handle.exit().remove();
31931 handle.enter().append("rect")
31932 .attr("class", function(d) { return "handle handle--" + d.type; })
31933 .attr("cursor", function(d) { return cursors[d.type]; });
31937 .attr("fill", "none")
31938 .attr("pointer-events", "all")
31939 .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)")
31940 .on("mousedown.brush touchstart.brush", started);
31943 brush.move = function(group, selection$$1) {
31944 if (group.selection) {
31946 .on("start.brush", function() { emitter(this, arguments).beforestart().start(); })
31947 .on("interrupt.brush end.brush", function() { emitter(this, arguments).end(); })
31948 .tween("brush", function() {
31950 state = that.__brush,
31951 emit = emitter(that, arguments),
31952 selection0 = state.selection,
31953 selection1 = dim.input(typeof selection$$1 === "function" ? selection$$1.apply(this, arguments) : selection$$1, state.extent),
31954 i = interpolate(selection0, selection1);
31956 function tween(t) {
31957 state.selection = t === 1 && empty$1(selection1) ? null : i(t);
31962 return selection0 && selection1 ? tween : tween(1);
31969 state = that.__brush,
31970 selection1 = dim.input(typeof selection$$1 === "function" ? selection$$1.apply(that, args) : selection$$1, state.extent),
31971 emit = emitter(that, args).beforestart();
31974 state.selection = selection1 == null || empty$1(selection1) ? null : selection1;
31976 emit.start().brush().end();
31981 function redraw() {
31982 var group = select(this),
31983 selection$$1 = local$1(this).selection;
31985 if (selection$$1) {
31986 group.selectAll(".selection")
31987 .style("display", null)
31988 .attr("x", selection$$1[0][0])
31989 .attr("y", selection$$1[0][1])
31990 .attr("width", selection$$1[1][0] - selection$$1[0][0])
31991 .attr("height", selection$$1[1][1] - selection$$1[0][1]);
31993 group.selectAll(".handle")
31994 .style("display", null)
31995 .attr("x", function(d) { return d.type[d.type.length - 1] === "e" ? selection$$1[1][0] - handleSize / 2 : selection$$1[0][0] - handleSize / 2; })
31996 .attr("y", function(d) { return d.type[0] === "s" ? selection$$1[1][1] - handleSize / 2 : selection$$1[0][1] - handleSize / 2; })
31997 .attr("width", function(d) { return d.type === "n" || d.type === "s" ? selection$$1[1][0] - selection$$1[0][0] + handleSize : handleSize; })
31998 .attr("height", function(d) { return d.type === "e" || d.type === "w" ? selection$$1[1][1] - selection$$1[0][1] + handleSize : handleSize; });
32002 group.selectAll(".selection,.handle")
32003 .style("display", "none")
32006 .attr("width", null)
32007 .attr("height", null);
32011 function emitter(that, args) {
32012 return that.__brush.emitter || new Emitter(that, args);
32015 function Emitter(that, args) {
32018 this.state = that.__brush;
32022 Emitter.prototype = {
32023 beforestart: function() {
32024 if (++this.active === 1) this.state.emitter = this, this.starting = true;
32027 start: function() {
32028 if (this.starting) this.starting = false, this.emit("start");
32031 brush: function() {
32032 this.emit("brush");
32036 if (--this.active === 0) delete this.state.emitter, this.emit("end");
32039 emit: function(type) {
32040 customEvent(new BrushEvent(brush, type, dim.output(this.state.selection)), listeners.apply, listeners, [type, this.that, this.args]);
32044 function started() {
32045 if (event.touches) { if (event.changedTouches.length < event.touches.length) return noevent$2(); }
32046 else if (touchending) return;
32047 if (!filter.apply(this, arguments)) return;
32050 type = event.target.__data__.type,
32051 mode = (event.metaKey ? type = "overlay" : type) === "selection" ? MODE_DRAG : (event.altKey ? MODE_CENTER : MODE_HANDLE),
32052 signX = dim === Y ? null : signsX[type],
32053 signY = dim === X ? null : signsY[type],
32054 state = local$1(that),
32055 extent = state.extent,
32056 selection$$1 = state.selection,
32057 W = extent[0][0], w0, w1,
32058 N = extent[0][1], n0, n1,
32059 E = extent[1][0], e0, e1,
32060 S = extent[1][1], s0, s1,
32064 shifting = signX && signY && event.shiftKey,
32067 point0 = mouse(that),
32069 emit = emitter(that, arguments).beforestart();
32071 if (type === "overlay") {
32072 state.selection = selection$$1 = [
32073 [w0 = dim === Y ? W : point0[0], n0 = dim === X ? N : point0[1]],
32074 [e0 = dim === Y ? E : w0, s0 = dim === X ? S : n0]
32077 w0 = selection$$1[0][0];
32078 n0 = selection$$1[0][1];
32079 e0 = selection$$1[1][0];
32080 s0 = selection$$1[1][1];
32088 var group = select(that)
32089 .attr("pointer-events", "none");
32091 var overlay = group.selectAll(".overlay")
32092 .attr("cursor", cursors[type]);
32094 if (event.touches) {
32096 .on("touchmove.brush", moved, true)
32097 .on("touchend.brush touchcancel.brush", ended, true);
32099 var view = select(event.view)
32100 .on("keydown.brush", keydowned, true)
32101 .on("keyup.brush", keyupped, true)
32102 .on("mousemove.brush", moved, true)
32103 .on("mouseup.brush", ended, true);
32105 dragDisable(event.view);
32114 var point1 = mouse(that);
32115 if (shifting && !lockX && !lockY) {
32116 if (Math.abs(point1[0] - point[0]) > Math.abs(point1[1] - point[1])) lockY = true;
32128 dx = point[0] - point0[0];
32129 dy = point[1] - point0[1];
32134 if (signX) dx = Math.max(W - w0, Math.min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx;
32135 if (signY) dy = Math.max(N - n0, Math.min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy;
32138 case MODE_HANDLE: {
32139 if (signX < 0) dx = Math.max(W - w0, Math.min(E - w0, dx)), w1 = w0 + dx, e1 = e0;
32140 else if (signX > 0) dx = Math.max(W - e0, Math.min(E - e0, dx)), w1 = w0, e1 = e0 + dx;
32141 if (signY < 0) dy = Math.max(N - n0, Math.min(S - n0, dy)), n1 = n0 + dy, s1 = s0;
32142 else if (signY > 0) dy = Math.max(N - s0, Math.min(S - s0, dy)), n1 = n0, s1 = s0 + dy;
32145 case MODE_CENTER: {
32146 if (signX) w1 = Math.max(W, Math.min(E, w0 - dx * signX)), e1 = Math.max(W, Math.min(E, e0 + dx * signX));
32147 if (signY) n1 = Math.max(N, Math.min(S, n0 - dy * signY)), s1 = Math.max(N, Math.min(S, s0 + dy * signY));
32154 t = w0, w0 = e0, e0 = t;
32155 t = w1, w1 = e1, e1 = t;
32156 if (type in flipX) overlay.attr("cursor", cursors[type = flipX[type]]);
32161 t = n0, n0 = s0, s0 = t;
32162 t = n1, n1 = s1, s1 = t;
32163 if (type in flipY) overlay.attr("cursor", cursors[type = flipY[type]]);
32166 if (state.selection) selection$$1 = state.selection; // May be set by brush.move!
32167 if (lockX) w1 = selection$$1[0][0], e1 = selection$$1[1][0];
32168 if (lockY) n1 = selection$$1[0][1], s1 = selection$$1[1][1];
32170 if (selection$$1[0][0] !== w1
32171 || selection$$1[0][1] !== n1
32172 || selection$$1[1][0] !== e1
32173 || selection$$1[1][1] !== s1) {
32174 state.selection = [[w1, n1], [e1, s1]];
32182 if (event.touches) {
32183 if (event.touches.length) return;
32184 if (touchending) clearTimeout(touchending);
32185 touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
32186 group.on("touchmove.brush touchend.brush touchcancel.brush", null);
32188 yesdrag(event.view, moving);
32189 view.on("keydown.brush keyup.brush mousemove.brush mouseup.brush", null);
32191 group.attr("pointer-events", "all");
32192 overlay.attr("cursor", cursors.overlay);
32193 if (state.selection) selection$$1 = state.selection; // May be set by brush.move (on start)!
32194 if (empty$1(selection$$1)) state.selection = null, redraw.call(that);
32198 function keydowned() {
32199 switch (event.keyCode) {
32200 case 16: { // SHIFT
32201 shifting = signX && signY;
32205 if (mode === MODE_HANDLE) {
32206 if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
32207 if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
32208 mode = MODE_CENTER;
32213 case 32: { // SPACE; takes priority over ALT
32214 if (mode === MODE_HANDLE || mode === MODE_CENTER) {
32215 if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx;
32216 if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy;
32218 overlay.attr("cursor", cursors.selection);
32228 function keyupped() {
32229 switch (event.keyCode) {
32230 case 16: { // SHIFT
32232 lockX = lockY = shifting = false;
32238 if (mode === MODE_CENTER) {
32239 if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
32240 if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
32241 mode = MODE_HANDLE;
32246 case 32: { // SPACE
32247 if (mode === MODE_SPACE) {
32248 if (event.altKey) {
32249 if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
32250 if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
32251 mode = MODE_CENTER;
32253 if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
32254 if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
32255 mode = MODE_HANDLE;
32257 overlay.attr("cursor", cursors[type]);
32268 function initialize() {
32269 var state = this.__brush || {selection: null};
32270 state.extent = extent.apply(this, arguments);
32275 brush.extent = function(_) {
32276 return arguments.length ? (extent = typeof _ === "function" ? _ : constant$11([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), brush) : extent;
32279 brush.filter = function(_) {
32280 return arguments.length ? (filter = typeof _ === "function" ? _ : constant$11(!!_), brush) : filter;
32283 brush.handleSize = function(_) {
32284 return arguments.length ? (handleSize = +_, brush) : handleSize;
32287 brush.on = function() {
32288 var value = listeners.on.apply(listeners, arguments);
32289 return value === listeners ? brush : value;
32295 var cos = Math.cos;
32296 var sin = Math.sin;
32297 var pi$3 = Math.PI;
32298 var halfPi$2 = pi$3 / 2;
32299 var tau$3 = pi$3 * 2;
32300 var max$1 = Math.max;
32302 function compareValue(compare) {
32303 return function(a, b) {
32305 a.source.value + a.target.value,
32306 b.source.value + b.target.value
32311 var chord = function() {
32314 sortSubgroups = null,
32317 function chord(matrix) {
32318 var n = matrix.length,
32320 groupIndex = range(n),
32321 subgroupIndex = [],
32323 groups = chords.groups = new Array(n),
32324 subgroups = new Array(n * n),
32332 // Compute the sum.
32333 k = 0, i = -1; while (++i < n) {
32334 x = 0, j = -1; while (++j < n) {
32338 subgroupIndex.push(range(n));
32343 if (sortGroups) groupIndex.sort(function(a, b) {
32344 return sortGroups(groupSums[a], groupSums[b]);
32348 if (sortSubgroups) subgroupIndex.forEach(function(d, i) {
32349 d.sort(function(a, b) {
32350 return sortSubgroups(matrix[i][a], matrix[i][b]);
32354 // Convert the sum to scaling factor for [0, 2pi].
32355 // TODO Allow start and end angle to be specified?
32356 // TODO Allow padding to be specified as percentage?
32357 k = max$1(0, tau$3 - padAngle * n) / k;
32358 dx = k ? padAngle : tau$3 / n;
32360 // Compute the start and end angle for each group and subgroup.
32361 // Note: Opera has a bug reordering object literal properties!
32362 x = 0, i = -1; while (++i < n) {
32363 x0 = x, j = -1; while (++j < n) {
32364 var di = groupIndex[i],
32365 dj = subgroupIndex[di][j],
32366 v = matrix[di][dj],
32369 subgroups[dj * n + di] = {
32381 value: groupSums[di]
32386 // Generate chords for each (non-empty) subgroup-subgroup link.
32387 i = -1; while (++i < n) {
32388 j = i - 1; while (++j < n) {
32389 var source = subgroups[j * n + i],
32390 target = subgroups[i * n + j];
32391 if (source.value || target.value) {
32392 chords.push(source.value < target.value
32393 ? {source: target, target: source}
32394 : {source: source, target: target});
32399 return sortChords ? chords.sort(sortChords) : chords;
32402 chord.padAngle = function(_) {
32403 return arguments.length ? (padAngle = max$1(0, _), chord) : padAngle;
32406 chord.sortGroups = function(_) {
32407 return arguments.length ? (sortGroups = _, chord) : sortGroups;
32410 chord.sortSubgroups = function(_) {
32411 return arguments.length ? (sortSubgroups = _, chord) : sortSubgroups;
32414 chord.sortChords = function(_) {
32415 return arguments.length ? (_ == null ? sortChords = null : (sortChords = compareValue(_))._ = _, chord) : sortChords && sortChords._;
32421 var slice$5 = Array.prototype.slice;
32423 var constant$12 = function(x) {
32424 return function() {
32429 function defaultSource(d) {
32433 function defaultTarget(d) {
32437 function defaultRadius$1(d) {
32441 function defaultStartAngle(d) {
32442 return d.startAngle;
32445 function defaultEndAngle(d) {
32449 var ribbon = function() {
32450 var source = defaultSource,
32451 target = defaultTarget,
32452 radius = defaultRadius$1,
32453 startAngle = defaultStartAngle,
32454 endAngle = defaultEndAngle,
32457 function ribbon() {
32459 argv = slice$5.call(arguments),
32460 s = source.apply(this, argv),
32461 t = target.apply(this, argv),
32462 sr = +radius.apply(this, (argv[0] = s, argv)),
32463 sa0 = startAngle.apply(this, argv) - halfPi$2,
32464 sa1 = endAngle.apply(this, argv) - halfPi$2,
32465 sx0 = sr * cos(sa0),
32466 sy0 = sr * sin(sa0),
32467 tr = +radius.apply(this, (argv[0] = t, argv)),
32468 ta0 = startAngle.apply(this, argv) - halfPi$2,
32469 ta1 = endAngle.apply(this, argv) - halfPi$2;
32471 if (!context) context = buffer = path();
32473 context.moveTo(sx0, sy0);
32474 context.arc(0, 0, sr, sa0, sa1);
32475 if (sa0 !== ta0 || sa1 !== ta1) { // TODO sr !== tr?
32476 context.quadraticCurveTo(0, 0, tr * cos(ta0), tr * sin(ta0));
32477 context.arc(0, 0, tr, ta0, ta1);
32479 context.quadraticCurveTo(0, 0, sx0, sy0);
32480 context.closePath();
32482 if (buffer) return context = null, buffer + "" || null;
32485 ribbon.radius = function(_) {
32486 return arguments.length ? (radius = typeof _ === "function" ? _ : constant$12(+_), ribbon) : radius;
32489 ribbon.startAngle = function(_) {
32490 return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$12(+_), ribbon) : startAngle;
32493 ribbon.endAngle = function(_) {
32494 return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$12(+_), ribbon) : endAngle;
32497 ribbon.source = function(_) {
32498 return arguments.length ? (source = _, ribbon) : source;
32501 ribbon.target = function(_) {
32502 return arguments.length ? (target = _, ribbon) : target;
32505 ribbon.context = function(_) {
32506 return arguments.length ? ((context = _ == null ? null : _), ribbon) : context;
32512 // Adds floating point numbers with twice the normal precision.
32513 // Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and
32514 // Fast Robust Geometric Predicates, Discrete & Computational Geometry 18(3)
32516 // Code adapted from GeographicLib by Charles F. F. Karney,
32517 // http://geographiclib.sourceforge.net/
32519 var adder = function() {
32527 Adder.prototype = {
32528 constructor: Adder,
32529 reset: function() {
32530 this.s = // rounded value
32531 this.t = 0; // exact error
32534 add$1(temp, y, this.t);
32535 add$1(this, temp.s, this.s);
32536 if (this.s) this.t += temp.t;
32537 else this.s = temp.t;
32539 valueOf: function() {
32544 var temp = new Adder;
32546 function add$1(adder, a, b) {
32547 var x = adder.s = a + b,
32550 adder.t = (a - av) + (b - bv);
32553 var epsilon$4 = 1e-6;
32554 var epsilon2$2 = 1e-12;
32555 var pi$4 = Math.PI;
32556 var halfPi$3 = pi$4 / 2;
32557 var quarterPi = pi$4 / 4;
32558 var tau$4 = pi$4 * 2;
32560 var degrees$1 = 180 / pi$4;
32561 var radians = pi$4 / 180;
32563 var abs = Math.abs;
32564 var atan = Math.atan;
32565 var atan2 = Math.atan2;
32566 var cos$1 = Math.cos;
32567 var ceil = Math.ceil;
32568 var exp = Math.exp;
32570 var log$1 = Math.log;
32571 var pow$1 = Math.pow;
32572 var sin$1 = Math.sin;
32573 var sign$1 = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; };
32574 var sqrt$1 = Math.sqrt;
32575 var tan = Math.tan;
32578 return x > 1 ? 0 : x < -1 ? pi$4 : Math.acos(x);
32581 function asin$1(x) {
32582 return x > 1 ? halfPi$3 : x < -1 ? -halfPi$3 : Math.asin(x);
32585 function haversin(x) {
32586 return (x = sin$1(x / 2)) * x;
32589 function noop$2() {}
32591 function streamGeometry(geometry, stream) {
32592 if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) {
32593 streamGeometryType[geometry.type](geometry, stream);
32597 var streamObjectType = {
32598 Feature: function(feature, stream) {
32599 streamGeometry(feature.geometry, stream);
32601 FeatureCollection: function(object, stream) {
32602 var features = object.features, i = -1, n = features.length;
32603 while (++i < n) streamGeometry(features[i].geometry, stream);
32607 var streamGeometryType = {
32608 Sphere: function(object, stream) {
32611 Point: function(object, stream) {
32612 object = object.coordinates;
32613 stream.point(object[0], object[1], object[2]);
32615 MultiPoint: function(object, stream) {
32616 var coordinates = object.coordinates, i = -1, n = coordinates.length;
32617 while (++i < n) object = coordinates[i], stream.point(object[0], object[1], object[2]);
32619 LineString: function(object, stream) {
32620 streamLine(object.coordinates, stream, 0);
32622 MultiLineString: function(object, stream) {
32623 var coordinates = object.coordinates, i = -1, n = coordinates.length;
32624 while (++i < n) streamLine(coordinates[i], stream, 0);
32626 Polygon: function(object, stream) {
32627 streamPolygon(object.coordinates, stream);
32629 MultiPolygon: function(object, stream) {
32630 var coordinates = object.coordinates, i = -1, n = coordinates.length;
32631 while (++i < n) streamPolygon(coordinates[i], stream);
32633 GeometryCollection: function(object, stream) {
32634 var geometries = object.geometries, i = -1, n = geometries.length;
32635 while (++i < n) streamGeometry(geometries[i], stream);
32639 function streamLine(coordinates, stream, closed) {
32640 var i = -1, n = coordinates.length - closed, coordinate;
32641 stream.lineStart();
32642 while (++i < n) coordinate = coordinates[i], stream.point(coordinate[0], coordinate[1], coordinate[2]);
32646 function streamPolygon(coordinates, stream) {
32647 var i = -1, n = coordinates.length;
32648 stream.polygonStart();
32649 while (++i < n) streamLine(coordinates[i], stream, 1);
32650 stream.polygonEnd();
32653 var geoStream = function(object, stream) {
32654 if (object && streamObjectType.hasOwnProperty(object.type)) {
32655 streamObjectType[object.type](object, stream);
32657 streamGeometry(object, stream);
32661 var areaRingSum = adder();
32663 var areaSum = adder();
32674 polygonStart: function() {
32675 areaRingSum.reset();
32676 areaStream.lineStart = areaRingStart;
32677 areaStream.lineEnd = areaRingEnd;
32679 polygonEnd: function() {
32680 var areaRing = +areaRingSum;
32681 areaSum.add(areaRing < 0 ? tau$4 + areaRing : areaRing);
32682 this.lineStart = this.lineEnd = this.point = noop$2;
32684 sphere: function() {
32685 areaSum.add(tau$4);
32689 function areaRingStart() {
32690 areaStream.point = areaPointFirst;
32693 function areaRingEnd() {
32694 areaPoint(lambda00, phi00);
32697 function areaPointFirst(lambda, phi) {
32698 areaStream.point = areaPoint;
32699 lambda00 = lambda, phi00 = phi;
32700 lambda *= radians, phi *= radians;
32701 lambda0 = lambda, cosPhi0 = cos$1(phi = phi / 2 + quarterPi), sinPhi0 = sin$1(phi);
32704 function areaPoint(lambda, phi) {
32705 lambda *= radians, phi *= radians;
32706 phi = phi / 2 + quarterPi; // half the angular distance from south pole
32708 // Spherical excess E for a spherical triangle with vertices: south pole,
32709 // previous point, current point. Uses a formula derived from Cagnoli’s
32710 // theorem. See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2).
32711 var dLambda = lambda - lambda0,
32712 sdLambda = dLambda >= 0 ? 1 : -1,
32713 adLambda = sdLambda * dLambda,
32714 cosPhi = cos$1(phi),
32715 sinPhi = sin$1(phi),
32716 k = sinPhi0 * sinPhi,
32717 u = cosPhi0 * cosPhi + k * cos$1(adLambda),
32718 v = k * sdLambda * sin$1(adLambda);
32719 areaRingSum.add(atan2(v, u));
32721 // Advance the previous points.
32722 lambda0 = lambda, cosPhi0 = cosPhi, sinPhi0 = sinPhi;
32725 var area$1 = function(object) {
32727 geoStream(object, areaStream);
32728 return areaSum * 2;
32731 function spherical(cartesian) {
32732 return [atan2(cartesian[1], cartesian[0]), asin$1(cartesian[2])];
32735 function cartesian(spherical) {
32736 var lambda = spherical[0], phi = spherical[1], cosPhi = cos$1(phi);
32737 return [cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi)];
32740 function cartesianDot(a, b) {
32741 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
32744 function cartesianCross(a, b) {
32745 return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
32749 function cartesianAddInPlace(a, b) {
32750 a[0] += b[0], a[1] += b[1], a[2] += b[2];
32753 function cartesianScale(vector, k) {
32754 return [vector[0] * k, vector[1] * k, vector[2] * k];
32758 function cartesianNormalizeInPlace(d) {
32759 var l = sqrt$1(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
32760 d[0] /= l, d[1] /= l, d[2] /= l;
32771 var deltaSum = adder();
32775 var boundsStream = {
32776 point: boundsPoint,
32777 lineStart: boundsLineStart,
32778 lineEnd: boundsLineEnd,
32779 polygonStart: function() {
32780 boundsStream.point = boundsRingPoint;
32781 boundsStream.lineStart = boundsRingStart;
32782 boundsStream.lineEnd = boundsRingEnd;
32784 areaStream.polygonStart();
32786 polygonEnd: function() {
32787 areaStream.polygonEnd();
32788 boundsStream.point = boundsPoint;
32789 boundsStream.lineStart = boundsLineStart;
32790 boundsStream.lineEnd = boundsLineEnd;
32791 if (areaRingSum < 0) lambda0$1 = -(lambda1 = 180), phi0 = -(phi1 = 90);
32792 else if (deltaSum > epsilon$4) phi1 = 90;
32793 else if (deltaSum < -epsilon$4) phi0 = -90;
32794 range$1[0] = lambda0$1, range$1[1] = lambda1;
32798 function boundsPoint(lambda, phi) {
32799 ranges.push(range$1 = [lambda0$1 = lambda, lambda1 = lambda]);
32800 if (phi < phi0) phi0 = phi;
32801 if (phi > phi1) phi1 = phi;
32804 function linePoint(lambda, phi) {
32805 var p = cartesian([lambda * radians, phi * radians]);
32807 var normal = cartesianCross(p0, p),
32808 equatorial = [normal[1], -normal[0], 0],
32809 inflection = cartesianCross(equatorial, normal);
32810 cartesianNormalizeInPlace(inflection);
32811 inflection = spherical(inflection);
32812 var delta = lambda - lambda2,
32813 sign$$1 = delta > 0 ? 1 : -1,
32814 lambdai = inflection[0] * degrees$1 * sign$$1,
32816 antimeridian = abs(delta) > 180;
32817 if (antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {
32818 phii = inflection[1] * degrees$1;
32819 if (phii > phi1) phi1 = phii;
32820 } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {
32821 phii = -inflection[1] * degrees$1;
32822 if (phii < phi0) phi0 = phii;
32824 if (phi < phi0) phi0 = phi;
32825 if (phi > phi1) phi1 = phi;
32827 if (antimeridian) {
32828 if (lambda < lambda2) {
32829 if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;
32831 if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;
32834 if (lambda1 >= lambda0$1) {
32835 if (lambda < lambda0$1) lambda0$1 = lambda;
32836 if (lambda > lambda1) lambda1 = lambda;
32838 if (lambda > lambda2) {
32839 if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;
32841 if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;
32846 boundsPoint(lambda, phi);
32848 p0 = p, lambda2 = lambda;
32851 function boundsLineStart() {
32852 boundsStream.point = linePoint;
32855 function boundsLineEnd() {
32856 range$1[0] = lambda0$1, range$1[1] = lambda1;
32857 boundsStream.point = boundsPoint;
32861 function boundsRingPoint(lambda, phi) {
32863 var delta = lambda - lambda2;
32864 deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta);
32866 lambda00$1 = lambda, phi00$1 = phi;
32868 areaStream.point(lambda, phi);
32869 linePoint(lambda, phi);
32872 function boundsRingStart() {
32873 areaStream.lineStart();
32876 function boundsRingEnd() {
32877 boundsRingPoint(lambda00$1, phi00$1);
32878 areaStream.lineEnd();
32879 if (abs(deltaSum) > epsilon$4) lambda0$1 = -(lambda1 = 180);
32880 range$1[0] = lambda0$1, range$1[1] = lambda1;
32884 // Finds the left-right distance between two longitudes.
32885 // This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want
32886 // the distance between ±180° to be 360°.
32887 function angle(lambda0, lambda1) {
32888 return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1;
32891 function rangeCompare(a, b) {
32892 return a[0] - b[0];
32895 function rangeContains(range, x) {
32896 return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x;
32899 var bounds = function(feature) {
32900 var i, n, a, b, merged, deltaMax, delta;
32902 phi1 = lambda1 = -(lambda0$1 = phi0 = Infinity);
32904 geoStream(feature, boundsStream);
32906 // First, sort ranges by their minimum longitudes.
32907 if (n = ranges.length) {
32908 ranges.sort(rangeCompare);
32910 // Then, merge any ranges that overlap.
32911 for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) {
32913 if (rangeContains(a, b[0]) || rangeContains(a, b[1])) {
32914 if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1];
32915 if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0];
32917 merged.push(a = b);
32921 // Finally, find the largest gap between the merged ranges.
32922 // The final bounding box will be the inverse of this gap.
32923 for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) {
32925 if ((delta = angle(a[1], b[0])) > deltaMax) deltaMax = delta, lambda0$1 = b[0], lambda1 = a[1];
32929 ranges = range$1 = null;
32931 return lambda0$1 === Infinity || phi0 === Infinity
32932 ? [[NaN, NaN], [NaN, NaN]]
32933 : [[lambda0$1, phi0], [lambda1, phi1]];
32951 var z0; // previous point
32953 var centroidStream = {
32955 point: centroidPoint,
32956 lineStart: centroidLineStart,
32957 lineEnd: centroidLineEnd,
32958 polygonStart: function() {
32959 centroidStream.lineStart = centroidRingStart;
32960 centroidStream.lineEnd = centroidRingEnd;
32962 polygonEnd: function() {
32963 centroidStream.lineStart = centroidLineStart;
32964 centroidStream.lineEnd = centroidLineEnd;
32968 // Arithmetic mean of Cartesian vectors.
32969 function centroidPoint(lambda, phi) {
32970 lambda *= radians, phi *= radians;
32971 var cosPhi = cos$1(phi);
32972 centroidPointCartesian(cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi));
32975 function centroidPointCartesian(x, y, z) {
32977 X0 += (x - X0) / W0;
32978 Y0 += (y - Y0) / W0;
32979 Z0 += (z - Z0) / W0;
32982 function centroidLineStart() {
32983 centroidStream.point = centroidLinePointFirst;
32986 function centroidLinePointFirst(lambda, phi) {
32987 lambda *= radians, phi *= radians;
32988 var cosPhi = cos$1(phi);
32989 x0 = cosPhi * cos$1(lambda);
32990 y0 = cosPhi * sin$1(lambda);
32992 centroidStream.point = centroidLinePoint;
32993 centroidPointCartesian(x0, y0, z0);
32996 function centroidLinePoint(lambda, phi) {
32997 lambda *= radians, phi *= radians;
32998 var cosPhi = cos$1(phi),
32999 x = cosPhi * cos$1(lambda),
33000 y = cosPhi * sin$1(lambda),
33002 w = atan2(sqrt$1((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z);
33004 X1 += w * (x0 + (x0 = x));
33005 Y1 += w * (y0 + (y0 = y));
33006 Z1 += w * (z0 + (z0 = z));
33007 centroidPointCartesian(x0, y0, z0);
33010 function centroidLineEnd() {
33011 centroidStream.point = centroidPoint;
33014 // See J. E. Brock, The Inertia Tensor for a Spherical Triangle,
33015 // J. Applied Mechanics 42, 239 (1975).
33016 function centroidRingStart() {
33017 centroidStream.point = centroidRingPointFirst;
33020 function centroidRingEnd() {
33021 centroidRingPoint(lambda00$2, phi00$2);
33022 centroidStream.point = centroidPoint;
33025 function centroidRingPointFirst(lambda, phi) {
33026 lambda00$2 = lambda, phi00$2 = phi;
33027 lambda *= radians, phi *= radians;
33028 centroidStream.point = centroidRingPoint;
33029 var cosPhi = cos$1(phi);
33030 x0 = cosPhi * cos$1(lambda);
33031 y0 = cosPhi * sin$1(lambda);
33033 centroidPointCartesian(x0, y0, z0);
33036 function centroidRingPoint(lambda, phi) {
33037 lambda *= radians, phi *= radians;
33038 var cosPhi = cos$1(phi),
33039 x = cosPhi * cos$1(lambda),
33040 y = cosPhi * sin$1(lambda),
33042 cx = y0 * z - z0 * y,
33043 cy = z0 * x - x0 * z,
33044 cz = x0 * y - y0 * x,
33045 m = sqrt$1(cx * cx + cy * cy + cz * cz),
33046 u = x0 * x + y0 * y + z0 * z,
33047 v = m && -acos(u) / m, // area weight
33048 w = atan2(m, u); // line weight
33053 X1 += w * (x0 + (x0 = x));
33054 Y1 += w * (y0 + (y0 = y));
33055 Z1 += w * (z0 + (z0 = z));
33056 centroidPointCartesian(x0, y0, z0);
33059 var d3GeoCentroid = function(object) {
33064 geoStream(object, centroidStream);
33069 m = x * x + y * y + z * z;
33071 // If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid.
33072 if (m < epsilon2$2) {
33073 x = X1, y = Y1, z = Z1;
33074 // If the feature has zero length, fall back to arithmetic mean of point vectors.
33075 if (W1 < epsilon$4) x = X0, y = Y0, z = Z0;
33076 m = x * x + y * y + z * z;
33077 // If the feature still has an undefined ccentroid, then return.
33078 if (m < epsilon2$2) return [NaN, NaN];
33081 return [atan2(y, x) * degrees$1, asin$1(z / sqrt$1(m)) * degrees$1];
33084 var constant$13 = function(x) {
33085 return function() {
33090 var compose = function(a, b) {
33092 function compose(x, y) {
33093 return x = a(x, y), b(x[0], x[1]);
33096 if (a.invert && b.invert) compose.invert = function(x, y) {
33097 return x = b.invert(x, y), x && a.invert(x[0], x[1]);
33103 function rotationIdentity(lambda, phi) {
33104 return [lambda > pi$4 ? lambda - tau$4 : lambda < -pi$4 ? lambda + tau$4 : lambda, phi];
33107 rotationIdentity.invert = rotationIdentity;
33109 function rotateRadians(deltaLambda, deltaPhi, deltaGamma) {
33110 return (deltaLambda %= tau$4) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma))
33111 : rotationLambda(deltaLambda))
33112 : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma)
33113 : rotationIdentity);
33116 function forwardRotationLambda(deltaLambda) {
33117 return function(lambda, phi) {
33118 return lambda += deltaLambda, [lambda > pi$4 ? lambda - tau$4 : lambda < -pi$4 ? lambda + tau$4 : lambda, phi];
33122 function rotationLambda(deltaLambda) {
33123 var rotation = forwardRotationLambda(deltaLambda);
33124 rotation.invert = forwardRotationLambda(-deltaLambda);
33128 function rotationPhiGamma(deltaPhi, deltaGamma) {
33129 var cosDeltaPhi = cos$1(deltaPhi),
33130 sinDeltaPhi = sin$1(deltaPhi),
33131 cosDeltaGamma = cos$1(deltaGamma),
33132 sinDeltaGamma = sin$1(deltaGamma);
33134 function rotation(lambda, phi) {
33135 var cosPhi = cos$1(phi),
33136 x = cos$1(lambda) * cosPhi,
33137 y = sin$1(lambda) * cosPhi,
33139 k = z * cosDeltaPhi + x * sinDeltaPhi;
33141 atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi),
33142 asin$1(k * cosDeltaGamma + y * sinDeltaGamma)
33146 rotation.invert = function(lambda, phi) {
33147 var cosPhi = cos$1(phi),
33148 x = cos$1(lambda) * cosPhi,
33149 y = sin$1(lambda) * cosPhi,
33151 k = z * cosDeltaGamma - y * sinDeltaGamma;
33153 atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi),
33154 asin$1(k * cosDeltaPhi - x * sinDeltaPhi)
33161 var rotation = function(rotate) {
33162 rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0);
33164 function forward(coordinates) {
33165 coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians);
33166 return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;
33169 forward.invert = function(coordinates) {
33170 coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians);
33171 return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;
33177 // Generates a circle centered at [0°, 0°], with a given radius and precision.
33178 function circleStream(stream, radius, delta, direction, t0, t1) {
33179 if (!delta) return;
33180 var cosRadius = cos$1(radius),
33181 sinRadius = sin$1(radius),
33182 step = direction * delta;
33184 t0 = radius + direction * tau$4;
33185 t1 = radius - step / 2;
33187 t0 = circleRadius(cosRadius, t0);
33188 t1 = circleRadius(cosRadius, t1);
33189 if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau$4;
33191 for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) {
33192 point = spherical([cosRadius, -sinRadius * cos$1(t), -sinRadius * sin$1(t)]);
33193 stream.point(point[0], point[1]);
33197 // Returns the signed angle of a cartesian point relative to [cosRadius, 0, 0].
33198 function circleRadius(cosRadius, point) {
33199 point = cartesian(point), point[0] -= cosRadius;
33200 cartesianNormalizeInPlace(point);
33201 var radius = acos(-point[1]);
33202 return ((-point[2] < 0 ? -radius : radius) + tau$4 - epsilon$4) % tau$4;
33205 var circle$1 = function() {
33206 var center = constant$13([0, 0]),
33207 radius = constant$13(90),
33208 precision = constant$13(6),
33211 stream = {point: point};
33213 function point(x, y) {
33214 ring.push(x = rotate(x, y));
33215 x[0] *= degrees$1, x[1] *= degrees$1;
33218 function circle() {
33219 var c = center.apply(this, arguments),
33220 r = radius.apply(this, arguments) * radians,
33221 p = precision.apply(this, arguments) * radians;
33223 rotate = rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert;
33224 circleStream(stream, r, p, 1);
33225 c = {type: "Polygon", coordinates: [ring]};
33226 ring = rotate = null;
33230 circle.center = function(_) {
33231 return arguments.length ? (center = typeof _ === "function" ? _ : constant$13([+_[0], +_[1]]), circle) : center;
33234 circle.radius = function(_) {
33235 return arguments.length ? (radius = typeof _ === "function" ? _ : constant$13(+_), circle) : radius;
33238 circle.precision = function(_) {
33239 return arguments.length ? (precision = typeof _ === "function" ? _ : constant$13(+_), circle) : precision;
33245 var clipBuffer = function() {
33249 point: function(x, y) {
33252 lineStart: function() {
33253 lines.push(line = []);
33256 rejoin: function() {
33257 if (lines.length > 1) lines.push(lines.pop().concat(lines.shift()));
33259 result: function() {
33260 var result = lines;
33268 var clipLine = function(a, b, x0, y0, x1, y1) {
33280 if (!dx && r > 0) return;
33283 if (r < t0) return;
33284 if (r < t1) t1 = r;
33285 } else if (dx > 0) {
33286 if (r > t1) return;
33287 if (r > t0) t0 = r;
33291 if (!dx && r < 0) return;
33294 if (r > t1) return;
33295 if (r > t0) t0 = r;
33296 } else if (dx > 0) {
33297 if (r < t0) return;
33298 if (r < t1) t1 = r;
33302 if (!dy && r > 0) return;
33305 if (r < t0) return;
33306 if (r < t1) t1 = r;
33307 } else if (dy > 0) {
33308 if (r > t1) return;
33309 if (r > t0) t0 = r;
33313 if (!dy && r < 0) return;
33316 if (r > t1) return;
33317 if (r > t0) t0 = r;
33318 } else if (dy > 0) {
33319 if (r < t0) return;
33320 if (r < t1) t1 = r;
33323 if (t0 > 0) a[0] = ax + t0 * dx, a[1] = ay + t0 * dy;
33324 if (t1 < 1) b[0] = ax + t1 * dx, b[1] = ay + t1 * dy;
33328 var pointEqual = function(a, b) {
33329 return abs(a[0] - b[0]) < epsilon$4 && abs(a[1] - b[1]) < epsilon$4;
33332 function Intersection(point, points, other, entry) {
33335 this.o = other; // another intersection
33336 this.e = entry; // is an entry?
33337 this.v = false; // visited
33338 this.n = this.p = null; // next & previous
33341 // A generalized polygon clipping algorithm: given a polygon that has been cut
33342 // into its visible line segments, and rejoins the segments by interpolating
33343 // along the clip edge.
33344 var clipPolygon = function(segments, compareIntersection, startInside, interpolate, stream) {
33350 segments.forEach(function(segment) {
33351 if ((n = segment.length - 1) <= 0) return;
33352 var n, p0 = segment[0], p1 = segment[n], x;
33354 // If the first and last points of a segment are coincident, then treat as a
33355 // closed ring. TODO if all rings are closed, then the winding order of the
33356 // exterior ring should be checked.
33357 if (pointEqual(p0, p1)) {
33358 stream.lineStart();
33359 for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]);
33364 subject.push(x = new Intersection(p0, segment, null, true));
33365 clip.push(x.o = new Intersection(p0, null, x, false));
33366 subject.push(x = new Intersection(p1, segment, null, false));
33367 clip.push(x.o = new Intersection(p1, null, x, true));
33370 if (!subject.length) return;
33372 clip.sort(compareIntersection);
33376 for (i = 0, n = clip.length; i < n; ++i) {
33377 clip[i].e = startInside = !startInside;
33380 var start = subject[0],
33385 // Find first unvisited intersection.
33386 var current = start,
33388 while (current.v) if ((current = current.n) === start) return;
33389 points = current.z;
33390 stream.lineStart();
33392 current.v = current.o.v = true;
33395 for (i = 0, n = points.length; i < n; ++i) stream.point((point = points[i])[0], point[1]);
33397 interpolate(current.x, current.n.x, 1, stream);
33399 current = current.n;
33402 points = current.p.z;
33403 for (i = points.length - 1; i >= 0; --i) stream.point((point = points[i])[0], point[1]);
33405 interpolate(current.x, current.p.x, -1, stream);
33407 current = current.p;
33409 current = current.o;
33410 points = current.z;
33411 isSubject = !isSubject;
33412 } while (!current.v);
33417 function link$1(array) {
33418 if (!(n = array.length)) return;
33424 a.n = b = array[i];
33428 a.n = b = array[0];
33433 var clipMin = -clipMax;
33435 // TODO Use d3-polygon’s polygonContains here for the ring check?
33436 // TODO Eliminate duplicate buffering in clipBuffer and polygon.push?
33438 function clipExtent(x0, y0, x1, y1) {
33440 function visible(x, y) {
33441 return x0 <= x && x <= x1 && y0 <= y && y <= y1;
33444 function interpolate(from, to, direction, stream) {
33447 || (a = corner(from, direction)) !== (a1 = corner(to, direction))
33448 || comparePoint(from, to) < 0 ^ direction > 0) {
33449 do stream.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);
33450 while ((a = (a + direction + 4) % 4) !== a1);
33452 stream.point(to[0], to[1]);
33456 function corner(p, direction) {
33457 return abs(p[0] - x0) < epsilon$4 ? direction > 0 ? 0 : 3
33458 : abs(p[0] - x1) < epsilon$4 ? direction > 0 ? 2 : 1
33459 : abs(p[1] - y0) < epsilon$4 ? direction > 0 ? 1 : 0
33460 : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon
33463 function compareIntersection(a, b) {
33464 return comparePoint(a.x, b.x);
33467 function comparePoint(a, b) {
33468 var ca = corner(a, 1),
33470 return ca !== cb ? ca - cb
33471 : ca === 0 ? b[1] - a[1]
33472 : ca === 1 ? a[0] - b[0]
33473 : ca === 2 ? a[1] - b[1]
33477 return function(stream) {
33478 var activeStream = stream,
33479 bufferStream = clipBuffer(),
33483 x__, y__, v__, // first point
33484 x_, y_, v_, // previous point
33490 lineStart: lineStart,
33492 polygonStart: polygonStart,
33493 polygonEnd: polygonEnd
33496 function point(x, y) {
33497 if (visible(x, y)) activeStream.point(x, y);
33500 function polygonInside() {
33503 for (var i = 0, n = polygon.length; i < n; ++i) {
33504 for (var ring = polygon[i], j = 1, m = ring.length, point = ring[0], a0, a1, b0 = point[0], b1 = point[1]; j < m; ++j) {
33505 a0 = b0, a1 = b1, point = ring[j], b0 = point[0], b1 = point[1];
33506 if (a1 <= y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1) * (x0 - a0)) ++winding; }
33507 else { if (b1 <= y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 - a0)) --winding; }
33514 // Buffer geometry within a polygon and then clip it en masse.
33515 function polygonStart() {
33516 activeStream = bufferStream, segments = [], polygon = [], clean = true;
33519 function polygonEnd() {
33520 var startInside = polygonInside(),
33521 cleanInside = clean && startInside,
33522 visible = (segments = merge(segments)).length;
33523 if (cleanInside || visible) {
33524 stream.polygonStart();
33526 stream.lineStart();
33527 interpolate(null, null, 1, stream);
33531 clipPolygon(segments, compareIntersection, startInside, interpolate, stream);
33533 stream.polygonEnd();
33535 activeStream = stream, segments = polygon = ring = null;
33538 function lineStart() {
33539 clipStream.point = linePoint;
33540 if (polygon) polygon.push(ring = []);
33546 // TODO rather than special-case polygons, simply handle them separately.
33547 // Ideally, coincident intersection points should be jittered to avoid
33548 // clipping issues.
33549 function lineEnd() {
33551 linePoint(x__, y__);
33552 if (v__ && v_) bufferStream.rejoin();
33553 segments.push(bufferStream.result());
33555 clipStream.point = point;
33556 if (v_) activeStream.lineEnd();
33559 function linePoint(x, y) {
33560 var v = visible(x, y);
33561 if (polygon) ring.push([x, y]);
33563 x__ = x, y__ = y, v__ = v;
33566 activeStream.lineStart();
33567 activeStream.point(x, y);
33570 if (v && v_) activeStream.point(x, y);
33572 var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))],
33573 b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))];
33574 if (clipLine(a, b, x0, y0, x1, y1)) {
33576 activeStream.lineStart();
33577 activeStream.point(a[0], a[1]);
33579 activeStream.point(b[0], b[1]);
33580 if (!v) activeStream.lineEnd();
33583 activeStream.lineStart();
33584 activeStream.point(x, y);
33589 x_ = x, y_ = y, v_ = v;
33596 var extent$1 = function() {
33606 stream: function(stream) {
33607 return cache && cacheStream === stream ? cache : cache = clipExtent(x0, y0, x1, y1)(cacheStream = stream);
33609 extent: function(_) {
33610 return arguments.length ? (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1], cache = cacheStream = null, clip) : [[x0, y0], [x1, y1]];
33615 var lengthSum = adder();
33620 var lengthStream = {
33623 lineStart: lengthLineStart,
33625 polygonStart: noop$2,
33629 function lengthLineStart() {
33630 lengthStream.point = lengthPointFirst;
33631 lengthStream.lineEnd = lengthLineEnd;
33634 function lengthLineEnd() {
33635 lengthStream.point = lengthStream.lineEnd = noop$2;
33638 function lengthPointFirst(lambda, phi) {
33639 lambda *= radians, phi *= radians;
33640 lambda0$2 = lambda, sinPhi0$1 = sin$1(phi), cosPhi0$1 = cos$1(phi);
33641 lengthStream.point = lengthPoint;
33644 function lengthPoint(lambda, phi) {
33645 lambda *= radians, phi *= radians;
33646 var sinPhi = sin$1(phi),
33647 cosPhi = cos$1(phi),
33648 delta = abs(lambda - lambda0$2),
33649 cosDelta = cos$1(delta),
33650 sinDelta = sin$1(delta),
33651 x = cosPhi * sinDelta,
33652 y = cosPhi0$1 * sinPhi - sinPhi0$1 * cosPhi * cosDelta,
33653 z = sinPhi0$1 * sinPhi + cosPhi0$1 * cosPhi * cosDelta;
33654 lengthSum.add(atan2(sqrt$1(x * x + y * y), z));
33655 lambda0$2 = lambda, sinPhi0$1 = sinPhi, cosPhi0$1 = cosPhi;
33658 var d3GeoLength = function(object) {
33660 geoStream(object, lengthStream);
33664 var coordinates = [null, null];
33665 var object$1 = {type: "LineString", coordinates: coordinates};
33667 var distance = function(a, b) {
33668 coordinates[0] = a;
33669 coordinates[1] = b;
33670 return d3GeoLength(object$1);
33673 function graticuleX(y0, y1, dy) {
33674 var y = range(y0, y1 - epsilon$4, dy).concat(y1);
33675 return function(x) { return y.map(function(y) { return [x, y]; }); };
33678 function graticuleY(x0, x1, dx) {
33679 var x = range(x0, x1 - epsilon$4, dx).concat(x1);
33680 return function(y) { return x.map(function(x) { return [x, y]; }); };
33683 function graticule() {
33684 var x1, x0, X1, X0,
33686 dx = 10, dy = dx, DX = 90, DY = 360,
33690 function graticule() {
33691 return {type: "MultiLineString", coordinates: lines()};
33695 return range(ceil(X0 / DX) * DX, X1, DX).map(X)
33696 .concat(range(ceil(Y0 / DY) * DY, Y1, DY).map(Y))
33697 .concat(range(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs(x % DX) > epsilon$4; }).map(x))
33698 .concat(range(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs(y % DY) > epsilon$4; }).map(y));
33701 graticule.lines = function() {
33702 return lines().map(function(coordinates) { return {type: "LineString", coordinates: coordinates}; });
33705 graticule.outline = function() {
33711 X(X1).reverse().slice(1),
33712 Y(Y0).reverse().slice(1))
33717 graticule.extent = function(_) {
33718 if (!arguments.length) return graticule.extentMinor();
33719 return graticule.extentMajor(_).extentMinor(_);
33722 graticule.extentMajor = function(_) {
33723 if (!arguments.length) return [[X0, Y0], [X1, Y1]];
33724 X0 = +_[0][0], X1 = +_[1][0];
33725 Y0 = +_[0][1], Y1 = +_[1][1];
33726 if (X0 > X1) _ = X0, X0 = X1, X1 = _;
33727 if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _;
33728 return graticule.precision(precision);
33731 graticule.extentMinor = function(_) {
33732 if (!arguments.length) return [[x0, y0], [x1, y1]];
33733 x0 = +_[0][0], x1 = +_[1][0];
33734 y0 = +_[0][1], y1 = +_[1][1];
33735 if (x0 > x1) _ = x0, x0 = x1, x1 = _;
33736 if (y0 > y1) _ = y0, y0 = y1, y1 = _;
33737 return graticule.precision(precision);
33740 graticule.step = function(_) {
33741 if (!arguments.length) return graticule.stepMinor();
33742 return graticule.stepMajor(_).stepMinor(_);
33745 graticule.stepMajor = function(_) {
33746 if (!arguments.length) return [DX, DY];
33747 DX = +_[0], DY = +_[1];
33751 graticule.stepMinor = function(_) {
33752 if (!arguments.length) return [dx, dy];
33753 dx = +_[0], dy = +_[1];
33757 graticule.precision = function(_) {
33758 if (!arguments.length) return precision;
33760 x = graticuleX(y0, y1, 90);
33761 y = graticuleY(x0, x1, precision);
33762 X = graticuleX(Y0, Y1, 90);
33763 Y = graticuleY(X0, X1, precision);
33768 .extentMajor([[-180, -90 + epsilon$4], [180, 90 - epsilon$4]])
33769 .extentMinor([[-180, -80 - epsilon$4], [180, 80 + epsilon$4]]);
33772 function graticule10() {
33773 return graticule()();
33776 var interpolate$2 = function(a, b) {
33777 var x0 = a[0] * radians,
33778 y0 = a[1] * radians,
33779 x1 = b[0] * radians,
33780 y1 = b[1] * radians,
33785 kx0 = cy0 * cos$1(x0),
33786 ky0 = cy0 * sin$1(x0),
33787 kx1 = cy1 * cos$1(x1),
33788 ky1 = cy1 * sin$1(x1),
33789 d = 2 * asin$1(sqrt$1(haversin(y1 - y0) + cy0 * cy1 * haversin(x1 - x0))),
33792 var interpolate = d ? function(t) {
33793 var B = sin$1(t *= d) / k,
33794 A = sin$1(d - t) / k,
33795 x = A * kx0 + B * kx1,
33796 y = A * ky0 + B * ky1,
33797 z = A * sy0 + B * sy1;
33799 atan2(y, x) * degrees$1,
33800 atan2(z, sqrt$1(x * x + y * y)) * degrees$1
33803 return [x0 * degrees$1, y0 * degrees$1];
33806 interpolate.distance = d;
33808 return interpolate;
33811 var identity$7 = function(x) {
33815 var areaSum$1 = adder();
33816 var areaRingSum$1 = adder();
33822 var areaStream$1 = {
33826 polygonStart: function() {
33827 areaStream$1.lineStart = areaRingStart$1;
33828 areaStream$1.lineEnd = areaRingEnd$1;
33830 polygonEnd: function() {
33831 areaStream$1.lineStart = areaStream$1.lineEnd = areaStream$1.point = noop$2;
33832 areaSum$1.add(abs(areaRingSum$1));
33833 areaRingSum$1.reset();
33835 result: function() {
33836 var area = areaSum$1 / 2;
33842 function areaRingStart$1() {
33843 areaStream$1.point = areaPointFirst$1;
33846 function areaPointFirst$1(x, y) {
33847 areaStream$1.point = areaPoint$1;
33848 x00 = x0$1 = x, y00 = y0$1 = y;
33851 function areaPoint$1(x, y) {
33852 areaRingSum$1.add(y0$1 * x - x0$1 * y);
33853 x0$1 = x, y0$1 = y;
33856 function areaRingEnd$1() {
33857 areaPoint$1(x00, y00);
33860 var x0$2 = Infinity;
33865 var boundsStream$1 = {
33866 point: boundsPoint$1,
33869 polygonStart: noop$2,
33870 polygonEnd: noop$2,
33871 result: function() {
33872 var bounds = [[x0$2, y0$2], [x1, y1]];
33873 x1 = y1 = -(y0$2 = x0$2 = Infinity);
33878 function boundsPoint$1(x, y) {
33879 if (x < x0$2) x0$2 = x;
33880 if (x > x1) x1 = x;
33881 if (y < y0$2) y0$2 = y;
33882 if (y > y1) y1 = y;
33885 // TODO Enforce positive area for exterior, negative area for interior?
33901 var centroidStream$1 = {
33902 point: centroidPoint$1,
33903 lineStart: centroidLineStart$1,
33904 lineEnd: centroidLineEnd$1,
33905 polygonStart: function() {
33906 centroidStream$1.lineStart = centroidRingStart$1;
33907 centroidStream$1.lineEnd = centroidRingEnd$1;
33909 polygonEnd: function() {
33910 centroidStream$1.point = centroidPoint$1;
33911 centroidStream$1.lineStart = centroidLineStart$1;
33912 centroidStream$1.lineEnd = centroidLineEnd$1;
33914 result: function() {
33915 var centroid = Z2$1 ? [X2$1 / Z2$1, Y2$1 / Z2$1]
33916 : Z1$1 ? [X1$1 / Z1$1, Y1$1 / Z1$1]
33917 : Z0$1 ? [X0$1 / Z0$1, Y0$1 / Z0$1]
33919 X0$1 = Y0$1 = Z0$1 =
33920 X1$1 = Y1$1 = Z1$1 =
33921 X2$1 = Y2$1 = Z2$1 = 0;
33926 function centroidPoint$1(x, y) {
33932 function centroidLineStart$1() {
33933 centroidStream$1.point = centroidPointFirstLine;
33936 function centroidPointFirstLine(x, y) {
33937 centroidStream$1.point = centroidPointLine;
33938 centroidPoint$1(x0$3 = x, y0$3 = y);
33941 function centroidPointLine(x, y) {
33942 var dx = x - x0$3, dy = y - y0$3, z = sqrt$1(dx * dx + dy * dy);
33943 X1$1 += z * (x0$3 + x) / 2;
33944 Y1$1 += z * (y0$3 + y) / 2;
33946 centroidPoint$1(x0$3 = x, y0$3 = y);
33949 function centroidLineEnd$1() {
33950 centroidStream$1.point = centroidPoint$1;
33953 function centroidRingStart$1() {
33954 centroidStream$1.point = centroidPointFirstRing;
33957 function centroidRingEnd$1() {
33958 centroidPointRing(x00$1, y00$1);
33961 function centroidPointFirstRing(x, y) {
33962 centroidStream$1.point = centroidPointRing;
33963 centroidPoint$1(x00$1 = x0$3 = x, y00$1 = y0$3 = y);
33966 function centroidPointRing(x, y) {
33969 z = sqrt$1(dx * dx + dy * dy);
33971 X1$1 += z * (x0$3 + x) / 2;
33972 Y1$1 += z * (y0$3 + y) / 2;
33975 z = y0$3 * x - x0$3 * y;
33976 X2$1 += z * (x0$3 + x);
33977 Y2$1 += z * (y0$3 + y);
33979 centroidPoint$1(x0$3 = x, y0$3 = y);
33982 function PathContext(context) {
33983 this._context = context;
33986 PathContext.prototype = {
33988 pointRadius: function(_) {
33989 return this._radius = _, this;
33991 polygonStart: function() {
33994 polygonEnd: function() {
33997 lineStart: function() {
34000 lineEnd: function() {
34001 if (this._line === 0) this._context.closePath();
34004 point: function(x, y) {
34005 switch (this._point) {
34007 this._context.moveTo(x, y);
34012 this._context.lineTo(x, y);
34016 this._context.moveTo(x + this._radius, y);
34017 this._context.arc(x, y, this._radius, 0, tau$4);
34025 function PathString() {
34029 PathString.prototype = {
34030 _circle: circle$2(4.5),
34031 pointRadius: function(_) {
34032 return this._circle = circle$2(_), this;
34034 polygonStart: function() {
34037 polygonEnd: function() {
34040 lineStart: function() {
34043 lineEnd: function() {
34044 if (this._line === 0) this._string.push("Z");
34047 point: function(x, y) {
34048 switch (this._point) {
34050 this._string.push("M", x, ",", y);
34055 this._string.push("L", x, ",", y);
34059 this._string.push("M", x, ",", y, this._circle);
34064 result: function() {
34065 if (this._string.length) {
34066 var result = this._string.join("");
34073 function circle$2(radius) {
34074 return "m0," + radius
34075 + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius
34076 + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius
34080 var index$5 = function(projection, context) {
34081 var pointRadius = 4.5,
34085 function path(object) {
34087 if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments));
34088 geoStream(object, projectionStream(contextStream));
34090 return contextStream.result();
34093 path.area = function(object) {
34094 geoStream(object, projectionStream(areaStream$1));
34095 return areaStream$1.result();
34098 path.bounds = function(object) {
34099 geoStream(object, projectionStream(boundsStream$1));
34100 return boundsStream$1.result();
34103 path.centroid = function(object) {
34104 geoStream(object, projectionStream(centroidStream$1));
34105 return centroidStream$1.result();
34108 path.projection = function(_) {
34109 return arguments.length ? (projectionStream = (projection = _) == null ? identity$7 : _.stream, path) : projection;
34112 path.context = function(_) {
34113 if (!arguments.length) return context;
34114 contextStream = (context = _) == null ? new PathString : new PathContext(_);
34115 if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius);
34119 path.pointRadius = function(_) {
34120 if (!arguments.length) return pointRadius;
34121 pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_);
34125 return path.projection(projection).context(context);
34128 var sum$2 = adder();
34130 var polygonContains = function(polygon, point) {
34131 var lambda = point[0],
34133 normal = [sin$1(lambda), -cos$1(lambda), 0],
34139 for (var i = 0, n = polygon.length; i < n; ++i) {
34140 if (!(m = (ring = polygon[i]).length)) continue;
34143 point0 = ring[m - 1],
34144 lambda0 = point0[0],
34145 phi0 = point0[1] / 2 + quarterPi,
34146 sinPhi0 = sin$1(phi0),
34147 cosPhi0 = cos$1(phi0);
34149 for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) {
34150 var point1 = ring[j],
34151 lambda1 = point1[0],
34152 phi1 = point1[1] / 2 + quarterPi,
34153 sinPhi1 = sin$1(phi1),
34154 cosPhi1 = cos$1(phi1),
34155 delta = lambda1 - lambda0,
34156 sign$$1 = delta >= 0 ? 1 : -1,
34157 absDelta = sign$$1 * delta,
34158 antimeridian = absDelta > pi$4,
34159 k = sinPhi0 * sinPhi1;
34161 sum$2.add(atan2(k * sign$$1 * sin$1(absDelta), cosPhi0 * cosPhi1 + k * cos$1(absDelta)));
34162 angle += antimeridian ? delta + sign$$1 * tau$4 : delta;
34164 // Are the longitudes either side of the point’s meridian (lambda),
34165 // and are the latitudes smaller than the parallel (phi)?
34166 if (antimeridian ^ lambda0 >= lambda ^ lambda1 >= lambda) {
34167 var arc = cartesianCross(cartesian(point0), cartesian(point1));
34168 cartesianNormalizeInPlace(arc);
34169 var intersection = cartesianCross(normal, arc);
34170 cartesianNormalizeInPlace(intersection);
34171 var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin$1(intersection[2]);
34172 if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) {
34173 winding += antimeridian ^ delta >= 0 ? 1 : -1;
34179 // First, determine whether the South pole is inside or outside:
34181 // It is inside if:
34182 // * the polygon winds around it in a clockwise direction.
34183 // * the polygon does not (cumulatively) wind around it, but has a negative
34184 // (counter-clockwise) area.
34186 // Second, count the (signed) number of times a segment crosses a lambda
34187 // from the point to the South pole. If it is zero, then the point is the
34188 // same side as the South pole.
34190 return (angle < -epsilon$4 || angle < epsilon$4 && sum$2 < -epsilon$4) ^ (winding & 1);
34193 var clip = function(pointVisible, clipLine, interpolate, start) {
34194 return function(rotate, sink) {
34195 var line = clipLine(sink),
34196 rotatedStart = rotate.invert(start[0], start[1]),
34197 ringBuffer = clipBuffer(),
34198 ringSink = clipLine(ringBuffer),
34199 polygonStarted = false,
34206 lineStart: lineStart,
34208 polygonStart: function() {
34209 clip.point = pointRing;
34210 clip.lineStart = ringStart;
34211 clip.lineEnd = ringEnd;
34215 polygonEnd: function() {
34216 clip.point = point;
34217 clip.lineStart = lineStart;
34218 clip.lineEnd = lineEnd;
34219 segments = merge(segments);
34220 var startInside = polygonContains(polygon, rotatedStart);
34221 if (segments.length) {
34222 if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
34223 clipPolygon(segments, compareIntersection, startInside, interpolate, sink);
34224 } else if (startInside) {
34225 if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
34227 interpolate(null, null, 1, sink);
34230 if (polygonStarted) sink.polygonEnd(), polygonStarted = false;
34231 segments = polygon = null;
34233 sphere: function() {
34234 sink.polygonStart();
34236 interpolate(null, null, 1, sink);
34242 function point(lambda, phi) {
34243 var point = rotate(lambda, phi);
34244 if (pointVisible(lambda = point[0], phi = point[1])) sink.point(lambda, phi);
34247 function pointLine(lambda, phi) {
34248 var point = rotate(lambda, phi);
34249 line.point(point[0], point[1]);
34252 function lineStart() {
34253 clip.point = pointLine;
34257 function lineEnd() {
34258 clip.point = point;
34262 function pointRing(lambda, phi) {
34263 ring.push([lambda, phi]);
34264 var point = rotate(lambda, phi);
34265 ringSink.point(point[0], point[1]);
34268 function ringStart() {
34269 ringSink.lineStart();
34273 function ringEnd() {
34274 pointRing(ring[0][0], ring[0][1]);
34275 ringSink.lineEnd();
34277 var clean = ringSink.clean(),
34278 ringSegments = ringBuffer.result(),
34279 i, n = ringSegments.length, m,
34284 polygon.push(ring);
34289 // No intersections.
34291 segment = ringSegments[0];
34292 if ((m = segment.length - 1) > 0) {
34293 if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
34295 for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]);
34301 // Rejoin connected segments.
34302 // TODO reuse ringBuffer.rejoin()?
34303 if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
34305 segments.push(ringSegments.filter(validSegment));
34312 function validSegment(segment) {
34313 return segment.length > 1;
34316 // Intersections are sorted along the clip edge. For both antimeridian cutting
34317 // and circle clipping, the same comparison is used.
34318 function compareIntersection(a, b) {
34319 return ((a = a.x)[0] < 0 ? a[1] - halfPi$3 - epsilon$4 : halfPi$3 - a[1])
34320 - ((b = b.x)[0] < 0 ? b[1] - halfPi$3 - epsilon$4 : halfPi$3 - b[1]);
34323 var clipAntimeridian = clip(
34324 function() { return true; },
34325 clipAntimeridianLine,
34326 clipAntimeridianInterpolate,
34330 // Takes a line and cuts into visible segments. Return values: 0 - there were
34331 // intersections or the line was empty; 1 - no intersections; 2 - there were
34332 // intersections, and the first and last segments should be rejoined.
34333 function clipAntimeridianLine(stream) {
34337 clean; // no intersections
34340 lineStart: function() {
34341 stream.lineStart();
34344 point: function(lambda1, phi1) {
34345 var sign1 = lambda1 > 0 ? pi$4 : -pi$4,
34346 delta = abs(lambda1 - lambda0);
34347 if (abs(delta - pi$4) < epsilon$4) { // line crosses a pole
34348 stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi$3 : -halfPi$3);
34349 stream.point(sign0, phi0);
34351 stream.lineStart();
34352 stream.point(sign1, phi0);
34353 stream.point(lambda1, phi0);
34355 } else if (sign0 !== sign1 && delta >= pi$4) { // line crosses antimeridian
34356 if (abs(lambda0 - sign0) < epsilon$4) lambda0 -= sign0 * epsilon$4; // handle degeneracies
34357 if (abs(lambda1 - sign1) < epsilon$4) lambda1 -= sign1 * epsilon$4;
34358 phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1);
34359 stream.point(sign0, phi0);
34361 stream.lineStart();
34362 stream.point(sign1, phi0);
34365 stream.point(lambda0 = lambda1, phi0 = phi1);
34368 lineEnd: function() {
34370 lambda0 = phi0 = NaN;
34372 clean: function() {
34373 return 2 - clean; // if intersections, rejoin first and last segments
34378 function clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) {
34381 sinLambda0Lambda1 = sin$1(lambda0 - lambda1);
34382 return abs(sinLambda0Lambda1) > epsilon$4
34383 ? atan((sin$1(phi0) * (cosPhi1 = cos$1(phi1)) * sin$1(lambda1)
34384 - sin$1(phi1) * (cosPhi0 = cos$1(phi0)) * sin$1(lambda0))
34385 / (cosPhi0 * cosPhi1 * sinLambda0Lambda1))
34386 : (phi0 + phi1) / 2;
34389 function clipAntimeridianInterpolate(from, to, direction, stream) {
34391 if (from == null) {
34392 phi = direction * halfPi$3;
34393 stream.point(-pi$4, phi);
34394 stream.point(0, phi);
34395 stream.point(pi$4, phi);
34396 stream.point(pi$4, 0);
34397 stream.point(pi$4, -phi);
34398 stream.point(0, -phi);
34399 stream.point(-pi$4, -phi);
34400 stream.point(-pi$4, 0);
34401 stream.point(-pi$4, phi);
34402 } else if (abs(from[0] - to[0]) > epsilon$4) {
34403 var lambda = from[0] < to[0] ? pi$4 : -pi$4;
34404 phi = direction * lambda / 2;
34405 stream.point(-lambda, phi);
34406 stream.point(0, phi);
34407 stream.point(lambda, phi);
34409 stream.point(to[0], to[1]);
34413 var clipCircle = function(radius, delta) {
34414 var cr = cos$1(radius),
34415 smallRadius = cr > 0,
34416 notHemisphere = abs(cr) > epsilon$4; // TODO optimise for this common case
34418 function interpolate(from, to, direction, stream) {
34419 circleStream(stream, radius, delta, direction, from, to);
34422 function visible(lambda, phi) {
34423 return cos$1(lambda) * cos$1(phi) > cr;
34426 // Takes a line and cuts into visible segments. Return values used for polygon
34427 // clipping: 0 - there were intersections or the line was empty; 1 - no
34428 // intersections 2 - there were intersections, and the first and last segments
34429 // should be rejoined.
34430 function clipLine(stream) {
34431 var point0, // previous point
34432 c0, // code for previous point
34433 v0, // visibility of previous point
34434 v00, // visibility of first point
34435 clean; // no intersections
34437 lineStart: function() {
34441 point: function(lambda, phi) {
34442 var point1 = [lambda, phi],
34444 v = visible(lambda, phi),
34446 ? v ? 0 : code(lambda, phi)
34447 : v ? code(lambda + (lambda < 0 ? pi$4 : -pi$4), phi) : 0;
34448 if (!point0 && (v00 = v0 = v)) stream.lineStart();
34449 // Handle degeneracies.
34450 // TODO ignore if not clipping polygons.
34452 point2 = intersect(point0, point1);
34453 if (pointEqual(point0, point2) || pointEqual(point1, point2)) {
34454 point1[0] += epsilon$4;
34455 point1[1] += epsilon$4;
34456 v = visible(point1[0], point1[1]);
34462 // outside going in
34463 stream.lineStart();
34464 point2 = intersect(point1, point0);
34465 stream.point(point2[0], point2[1]);
34467 // inside going out
34468 point2 = intersect(point0, point1);
34469 stream.point(point2[0], point2[1]);
34473 } else if (notHemisphere && point0 && smallRadius ^ v) {
34475 // If the codes for two points are different, or are both zero,
34476 // and there this segment intersects with the small circle.
34477 if (!(c & c0) && (t = intersect(point1, point0, true))) {
34480 stream.lineStart();
34481 stream.point(t[0][0], t[0][1]);
34482 stream.point(t[1][0], t[1][1]);
34485 stream.point(t[1][0], t[1][1]);
34487 stream.lineStart();
34488 stream.point(t[0][0], t[0][1]);
34492 if (v && (!point0 || !pointEqual(point0, point1))) {
34493 stream.point(point1[0], point1[1]);
34495 point0 = point1, v0 = v, c0 = c;
34497 lineEnd: function() {
34498 if (v0) stream.lineEnd();
34501 // Rejoin first and last segments if there were intersections and the first
34502 // and last points were visible.
34503 clean: function() {
34504 return clean | ((v00 && v0) << 1);
34509 // Intersects the great circle between a and b with the clip circle.
34510 function intersect(a, b, two) {
34511 var pa = cartesian(a),
34514 // We have two planes, n1.p = d1 and n2.p = d2.
34515 // Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2).
34516 var n1 = [1, 0, 0], // normal
34517 n2 = cartesianCross(pa, pb),
34518 n2n2 = cartesianDot(n2, n2),
34519 n1n2 = n2[0], // cartesianDot(n1, n2),
34520 determinant = n2n2 - n1n2 * n1n2;
34522 // Two polar points.
34523 if (!determinant) return !two && a;
34525 var c1 = cr * n2n2 / determinant,
34526 c2 = -cr * n1n2 / determinant,
34527 n1xn2 = cartesianCross(n1, n2),
34528 A = cartesianScale(n1, c1),
34529 B = cartesianScale(n2, c2);
34530 cartesianAddInPlace(A, B);
34532 // Solve |p(t)|^2 = 1.
34534 w = cartesianDot(A, u),
34535 uu = cartesianDot(u, u),
34536 t2 = w * w - uu * (cartesianDot(A, A) - 1);
34538 if (t2 < 0) return;
34540 var t = sqrt$1(t2),
34541 q = cartesianScale(u, (-w - t) / uu);
34542 cartesianAddInPlace(q, A);
34545 if (!two) return q;
34547 // Two intersection points.
34548 var lambda0 = a[0],
34554 if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z;
34556 var delta = lambda1 - lambda0,
34557 polar = abs(delta - pi$4) < epsilon$4,
34558 meridian = polar || delta < epsilon$4;
34560 if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z;
34562 // Check that the first point is between a and b.
34565 ? phi0 + phi1 > 0 ^ q[1] < (abs(q[0] - lambda0) < epsilon$4 ? phi0 : phi1)
34566 : phi0 <= q[1] && q[1] <= phi1
34567 : delta > pi$4 ^ (lambda0 <= q[0] && q[0] <= lambda1)) {
34568 var q1 = cartesianScale(u, (-w + t) / uu);
34569 cartesianAddInPlace(q1, A);
34570 return [q, spherical(q1)];
34574 // Generates a 4-bit vector representing the location of a point relative to
34575 // the small circle's bounding box.
34576 function code(lambda, phi) {
34577 var r = smallRadius ? radius : pi$4 - radius,
34579 if (lambda < -r) code |= 1; // left
34580 else if (lambda > r) code |= 2; // right
34581 if (phi < -r) code |= 4; // below
34582 else if (phi > r) code |= 8; // above
34586 return clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi$4, radius - pi$4]);
34589 var transform$1 = function(methods) {
34591 stream: transformer(methods)
34595 function transformer(methods) {
34596 return function(stream) {
34597 var s = new TransformStream;
34598 for (var key in methods) s[key] = methods[key];
34604 function TransformStream() {}
34606 TransformStream.prototype = {
34607 constructor: TransformStream,
34608 point: function(x, y) { this.stream.point(x, y); },
34609 sphere: function() { this.stream.sphere(); },
34610 lineStart: function() { this.stream.lineStart(); },
34611 lineEnd: function() { this.stream.lineEnd(); },
34612 polygonStart: function() { this.stream.polygonStart(); },
34613 polygonEnd: function() { this.stream.polygonEnd(); }
34616 function fitExtent(projection, extent, object) {
34617 var w = extent[1][0] - extent[0][0],
34618 h = extent[1][1] - extent[0][1],
34619 clip = projection.clipExtent && projection.clipExtent();
34623 .translate([0, 0]);
34625 if (clip != null) projection.clipExtent(null);
34627 geoStream(object, projection.stream(boundsStream$1));
34629 var b = boundsStream$1.result(),
34630 k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])),
34631 x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2,
34632 y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2;
34634 if (clip != null) projection.clipExtent(clip);
34638 .translate([x, y]);
34641 function fitSize(projection, size, object) {
34642 return fitExtent(projection, [[0, 0], size], object);
34646 var cosMinDistance = cos$1(30 * radians); // cos(minimum angular distance)
34648 var resample = function(project, delta2) {
34649 return +delta2 ? resample$1(project, delta2) : resampleNone(project);
34652 function resampleNone(project) {
34653 return transformer({
34654 point: function(x, y) {
34656 this.stream.point(x[0], x[1]);
34661 function resample$1(project, delta2) {
34663 function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1, b1, c1, depth, stream) {
34666 d2 = dx * dx + dy * dy;
34667 if (d2 > 4 * delta2 && depth--) {
34671 m = sqrt$1(a * a + b * b + c * c),
34672 phi2 = asin$1(c /= m),
34673 lambda2 = abs(abs(c) - 1) < epsilon$4 || abs(lambda0 - lambda1) < epsilon$4 ? (lambda0 + lambda1) / 2 : atan2(b, a),
34674 p = project(lambda2, phi2),
34679 dz = dy * dx2 - dx * dy2;
34680 if (dz * dz / d2 > delta2 // perpendicular projected distance
34681 || abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close to an end
34682 || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance
34683 resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /= m, b /= m, c, depth, stream);
34684 stream.point(x2, y2);
34685 resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c1, depth, stream);
34689 return function(stream) {
34690 var lambda00, x00, y00, a00, b00, c00, // first point
34691 lambda0, x0, y0, a0, b0, c0; // previous point
34693 var resampleStream = {
34695 lineStart: lineStart,
34697 polygonStart: function() { stream.polygonStart(); resampleStream.lineStart = ringStart; },
34698 polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStart = lineStart; }
34701 function point(x, y) {
34703 stream.point(x[0], x[1]);
34706 function lineStart() {
34708 resampleStream.point = linePoint;
34709 stream.lineStart();
34712 function linePoint(lambda, phi) {
34713 var c = cartesian([lambda, phi]), p = project(lambda, phi);
34714 resampleLineTo(x0, y0, lambda0, a0, b0, c0, x0 = p[0], y0 = p[1], lambda0 = lambda, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream);
34715 stream.point(x0, y0);
34718 function lineEnd() {
34719 resampleStream.point = point;
34723 function ringStart() {
34725 resampleStream.point = ringPoint;
34726 resampleStream.lineEnd = ringEnd;
34729 function ringPoint(lambda, phi) {
34730 linePoint(lambda00 = lambda, phi), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;
34731 resampleStream.point = linePoint;
34734 function ringEnd() {
34735 resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, b00, c00, maxDepth, stream);
34736 resampleStream.lineEnd = lineEnd;
34740 return resampleStream;
34744 var transformRadians = transformer({
34745 point: function(x, y) {
34746 this.stream.point(x * radians, y * radians);
34750 function projection(project) {
34751 return projectionMutator(function() { return project; })();
34754 function projectionMutator(projectAt) {
34757 x = 480, y = 250, // translate
34758 dx, dy, lambda = 0, phi = 0, // center
34759 deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, projectRotate, // rotate
34760 theta = null, preclip = clipAntimeridian, // clip angle
34761 x0 = null, y0, x1, y1, postclip = identity$7, // clip extent
34762 delta2 = 0.5, projectResample = resample(projectTransform, delta2), // precision
34766 function projection(point) {
34767 point = projectRotate(point[0] * radians, point[1] * radians);
34768 return [point[0] * k + dx, dy - point[1] * k];
34771 function invert(point) {
34772 point = projectRotate.invert((point[0] - dx) / k, (dy - point[1]) / k);
34773 return point && [point[0] * degrees$1, point[1] * degrees$1];
34776 function projectTransform(x, y) {
34777 return x = project(x, y), [x[0] * k + dx, dy - x[1] * k];
34780 projection.stream = function(stream) {
34781 return cache && cacheStream === stream ? cache : cache = transformRadians(preclip(rotate, projectResample(postclip(cacheStream = stream))));
34784 projection.clipAngle = function(_) {
34785 return arguments.length ? (preclip = +_ ? clipCircle(theta = _ * radians, 6 * radians) : (theta = null, clipAntimeridian), reset()) : theta * degrees$1;
34788 projection.clipExtent = function(_) {
34789 return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$7) : clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];
34792 projection.scale = function(_) {
34793 return arguments.length ? (k = +_, recenter()) : k;
34796 projection.translate = function(_) {
34797 return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y];
34800 projection.center = function(_) {
34801 return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees$1, phi * degrees$1];
34804 projection.rotate = function(_) {
34805 return arguments.length ? (deltaLambda = _[0] % 360 * radians, deltaPhi = _[1] % 360 * radians, deltaGamma = _.length > 2 ? _[2] % 360 * radians : 0, recenter()) : [deltaLambda * degrees$1, deltaPhi * degrees$1, deltaGamma * degrees$1];
34808 projection.precision = function(_) {
34809 return arguments.length ? (projectResample = resample(projectTransform, delta2 = _ * _), reset()) : sqrt$1(delta2);
34812 projection.fitExtent = function(extent, object) {
34813 return fitExtent(projection, extent, object);
34816 projection.fitSize = function(size, object) {
34817 return fitSize(projection, size, object);
34820 function recenter() {
34821 projectRotate = compose(rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma), project);
34822 var center = project(lambda, phi);
34823 dx = x - center[0] * k;
34824 dy = y + center[1] * k;
34829 cache = cacheStream = null;
34833 return function() {
34834 project = projectAt.apply(this, arguments);
34835 projection.invert = project.invert && invert;
34840 function conicProjection(projectAt) {
34843 m = projectionMutator(projectAt),
34846 p.parallels = function(_) {
34847 return arguments.length ? m(phi0 = _[0] * radians, phi1 = _[1] * radians) : [phi0 * degrees$1, phi1 * degrees$1];
34853 function cylindricalEqualAreaRaw(phi0) {
34854 var cosPhi0 = cos$1(phi0);
34856 function forward(lambda, phi) {
34857 return [lambda * cosPhi0, sin$1(phi) / cosPhi0];
34860 forward.invert = function(x, y) {
34861 return [x / cosPhi0, asin$1(y * cosPhi0)];
34867 function conicEqualAreaRaw(y0, y1) {
34868 var sy0 = sin$1(y0), n = (sy0 + sin$1(y1)) / 2;
34870 // Are the parallels symmetrical around the Equator?
34871 if (abs(n) < epsilon$4) return cylindricalEqualAreaRaw(y0);
34873 var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt$1(c) / n;
34875 function project(x, y) {
34876 var r = sqrt$1(c - 2 * n * sin$1(y)) / n;
34877 return [r * sin$1(x *= n), r0 - r * cos$1(x)];
34880 project.invert = function(x, y) {
34882 return [atan2(x, abs(r0y)) / n * sign$1(r0y), asin$1((c - (x * x + r0y * r0y) * n * n) / (2 * n))];
34888 var conicEqualArea = function() {
34889 return conicProjection(conicEqualAreaRaw)
34891 .center([0, 33.6442]);
34894 var albers = function() {
34895 return conicEqualArea()
34896 .parallels([29.5, 45.5])
34898 .translate([480, 250])
34900 .center([-0.6, 38.7]);
34903 // The projections must have mutually exclusive clip regions on the sphere,
34904 // as this will avoid emitting interleaving lines and polygons.
34905 function multiplex(streams) {
34906 var n = streams.length;
34908 point: function(x, y) { var i = -1; while (++i < n) streams[i].point(x, y); },
34909 sphere: function() { var i = -1; while (++i < n) streams[i].sphere(); },
34910 lineStart: function() { var i = -1; while (++i < n) streams[i].lineStart(); },
34911 lineEnd: function() { var i = -1; while (++i < n) streams[i].lineEnd(); },
34912 polygonStart: function() { var i = -1; while (++i < n) streams[i].polygonStart(); },
34913 polygonEnd: function() { var i = -1; while (++i < n) streams[i].polygonEnd(); }
34917 // A composite projection for the United States, configured by default for
34918 // 960×500. The projection also works quite well at 960×600 if you change the
34919 // scale to 1285 and adjust the translate accordingly. The set of standard
34920 // parallels for each region comes from USGS, which is published here:
34921 // http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers
34922 var albersUsa = function() {
34925 lower48 = albers(), lower48Point,
34926 alaska = conicEqualArea().rotate([154, 0]).center([-2, 58.5]).parallels([55, 65]), alaskaPoint, // EPSG:3338
34927 hawaii = conicEqualArea().rotate([157, 0]).center([-3, 19.9]).parallels([8, 18]), hawaiiPoint, // ESRI:102007
34928 point, pointStream = {point: function(x, y) { point = [x, y]; }};
34930 function albersUsa(coordinates) {
34931 var x = coordinates[0], y = coordinates[1];
34932 return point = null,
34933 (lower48Point.point(x, y), point)
34934 || (alaskaPoint.point(x, y), point)
34935 || (hawaiiPoint.point(x, y), point);
34938 albersUsa.invert = function(coordinates) {
34939 var k = lower48.scale(),
34940 t = lower48.translate(),
34941 x = (coordinates[0] - t[0]) / k,
34942 y = (coordinates[1] - t[1]) / k;
34943 return (y >= 0.120 && y < 0.234 && x >= -0.425 && x < -0.214 ? alaska
34944 : y >= 0.166 && y < 0.234 && x >= -0.214 && x < -0.115 ? hawaii
34945 : lower48).invert(coordinates);
34948 albersUsa.stream = function(stream) {
34949 return cache && cacheStream === stream ? cache : cache = multiplex([lower48.stream(cacheStream = stream), alaska.stream(stream), hawaii.stream(stream)]);
34952 albersUsa.precision = function(_) {
34953 if (!arguments.length) return lower48.precision();
34954 lower48.precision(_), alaska.precision(_), hawaii.precision(_);
34958 albersUsa.scale = function(_) {
34959 if (!arguments.length) return lower48.scale();
34960 lower48.scale(_), alaska.scale(_ * 0.35), hawaii.scale(_);
34961 return albersUsa.translate(lower48.translate());
34964 albersUsa.translate = function(_) {
34965 if (!arguments.length) return lower48.translate();
34966 var k = lower48.scale(), x = +_[0], y = +_[1];
34968 lower48Point = lower48
34970 .clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]])
34971 .stream(pointStream);
34973 alaskaPoint = alaska
34974 .translate([x - 0.307 * k, y + 0.201 * k])
34975 .clipExtent([[x - 0.425 * k + epsilon$4, y + 0.120 * k + epsilon$4], [x - 0.214 * k - epsilon$4, y + 0.234 * k - epsilon$4]])
34976 .stream(pointStream);
34978 hawaiiPoint = hawaii
34979 .translate([x - 0.205 * k, y + 0.212 * k])
34980 .clipExtent([[x - 0.214 * k + epsilon$4, y + 0.166 * k + epsilon$4], [x - 0.115 * k - epsilon$4, y + 0.234 * k - epsilon$4]])
34981 .stream(pointStream);
34986 albersUsa.fitExtent = function(extent, object) {
34987 return fitExtent(albersUsa, extent, object);
34990 albersUsa.fitSize = function(size, object) {
34991 return fitSize(albersUsa, size, object);
34995 cache = cacheStream = null;
34999 return albersUsa.scale(1070);
35002 function azimuthalRaw(scale) {
35003 return function(x, y) {
35006 k = scale(cx * cy);
35014 function azimuthalInvert(angle) {
35015 return function(x, y) {
35016 var z = sqrt$1(x * x + y * y),
35021 atan2(x * sc, z * cc),
35022 asin$1(z && y * sc / z)
35027 var azimuthalEqualAreaRaw = azimuthalRaw(function(cxcy) {
35028 return sqrt$1(2 / (1 + cxcy));
35031 azimuthalEqualAreaRaw.invert = azimuthalInvert(function(z) {
35032 return 2 * asin$1(z / 2);
35035 var azimuthalEqualArea = function() {
35036 return projection(azimuthalEqualAreaRaw)
35038 .clipAngle(180 - 1e-3);
35041 var azimuthalEquidistantRaw = azimuthalRaw(function(c) {
35042 return (c = acos(c)) && c / sin$1(c);
35045 azimuthalEquidistantRaw.invert = azimuthalInvert(function(z) {
35049 var azimuthalEquidistant = function() {
35050 return projection(azimuthalEquidistantRaw)
35052 .clipAngle(180 - 1e-3);
35055 function mercatorRaw(lambda, phi) {
35056 return [lambda, log$1(tan((halfPi$3 + phi) / 2))];
35059 mercatorRaw.invert = function(x, y) {
35060 return [x, 2 * atan(exp(y)) - halfPi$3];
35063 var mercator = function() {
35064 return mercatorProjection(mercatorRaw)
35065 .scale(961 / tau$4);
35068 function mercatorProjection(project) {
35069 var m = projection(project),
35071 translate = m.translate,
35072 clipExtent = m.clipExtent,
35075 m.scale = function(_) {
35076 return arguments.length ? (scale(_), clipAuto && m.clipExtent(null), m) : scale();
35079 m.translate = function(_) {
35080 return arguments.length ? (translate(_), clipAuto && m.clipExtent(null), m) : translate();
35083 m.clipExtent = function(_) {
35084 if (!arguments.length) return clipAuto ? null : clipExtent();
35085 if (clipAuto = _ == null) {
35086 var k = pi$4 * scale(),
35088 _ = [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]];
35094 return m.clipExtent(null);
35098 return tan((halfPi$3 + y) / 2);
35101 function conicConformalRaw(y0, y1) {
35102 var cy0 = cos$1(y0),
35103 n = y0 === y1 ? sin$1(y0) : log$1(cy0 / cos$1(y1)) / log$1(tany(y1) / tany(y0)),
35104 f = cy0 * pow$1(tany(y0), n) / n;
35106 if (!n) return mercatorRaw;
35108 function project(x, y) {
35109 if (f > 0) { if (y < -halfPi$3 + epsilon$4) y = -halfPi$3 + epsilon$4; }
35110 else { if (y > halfPi$3 - epsilon$4) y = halfPi$3 - epsilon$4; }
35111 var r = f / pow$1(tany(y), n);
35112 return [r * sin$1(n * x), f - r * cos$1(n * x)];
35115 project.invert = function(x, y) {
35116 var fy = f - y, r = sign$1(n) * sqrt$1(x * x + fy * fy);
35117 return [atan2(x, abs(fy)) / n * sign$1(fy), 2 * atan(pow$1(f / r, 1 / n)) - halfPi$3];
35123 var conicConformal = function() {
35124 return conicProjection(conicConformalRaw)
35126 .parallels([30, 30]);
35129 function equirectangularRaw(lambda, phi) {
35130 return [lambda, phi];
35133 equirectangularRaw.invert = equirectangularRaw;
35135 var equirectangular = function() {
35136 return projection(equirectangularRaw)
35140 function conicEquidistantRaw(y0, y1) {
35141 var cy0 = cos$1(y0),
35142 n = y0 === y1 ? sin$1(y0) : (cy0 - cos$1(y1)) / (y1 - y0),
35145 if (abs(n) < epsilon$4) return equirectangularRaw;
35147 function project(x, y) {
35148 var gy = g - y, nx = n * x;
35149 return [gy * sin$1(nx), g - gy * cos$1(nx)];
35152 project.invert = function(x, y) {
35154 return [atan2(x, abs(gy)) / n * sign$1(gy), g - sign$1(n) * sqrt$1(x * x + gy * gy)];
35160 var conicEquidistant = function() {
35161 return conicProjection(conicEquidistantRaw)
35163 .center([0, 13.9389]);
35166 function gnomonicRaw(x, y) {
35167 var cy = cos$1(y), k = cos$1(x) * cy;
35168 return [cy * sin$1(x) / k, sin$1(y) / k];
35171 gnomonicRaw.invert = azimuthalInvert(atan);
35173 var gnomonic = function() {
35174 return projection(gnomonicRaw)
35179 function scaleTranslate(k, tx, ty) {
35180 return k === 1 && tx === 0 && ty === 0 ? identity$7 : transformer({
35181 point: function(x, y) {
35182 this.stream.point(x * k + tx, y * k + ty);
35187 var identity$8 = function() {
35188 var k = 1, tx = 0, ty = 0, transform = identity$7, // scale and translate
35189 x0 = null, y0, x1, y1, clip = identity$7, // clip extent
35195 cache = cacheStream = null;
35199 return projection = {
35200 stream: function(stream) {
35201 return cache && cacheStream === stream ? cache : cache = transform(clip(cacheStream = stream));
35203 clipExtent: function(_) {
35204 return arguments.length ? (clip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$7) : clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];
35206 scale: function(_) {
35207 return arguments.length ? (transform = scaleTranslate(k = +_, tx, ty), reset()) : k;
35209 translate: function(_) {
35210 return arguments.length ? (transform = scaleTranslate(k, tx = +_[0], ty = +_[1]), reset()) : [tx, ty];
35212 fitExtent: function(extent, object) {
35213 return fitExtent(projection, extent, object);
35215 fitSize: function(size, object) {
35216 return fitSize(projection, size, object);
35221 function orthographicRaw(x, y) {
35222 return [cos$1(y) * sin$1(x), sin$1(y)];
35225 orthographicRaw.invert = azimuthalInvert(asin$1);
35227 var orthographic = function() {
35228 return projection(orthographicRaw)
35230 .clipAngle(90 + epsilon$4);
35233 function stereographicRaw(x, y) {
35234 var cy = cos$1(y), k = 1 + cos$1(x) * cy;
35235 return [cy * sin$1(x) / k, sin$1(y) / k];
35238 stereographicRaw.invert = azimuthalInvert(function(z) {
35239 return 2 * atan(z);
35242 var stereographic = function() {
35243 return projection(stereographicRaw)
35248 function transverseMercatorRaw(lambda, phi) {
35249 return [log$1(tan((halfPi$3 + phi) / 2)), -lambda];
35252 transverseMercatorRaw.invert = function(x, y) {
35253 return [-y, 2 * atan(exp(x)) - halfPi$3];
35256 var transverseMercator = function() {
35257 var m = mercatorProjection(transverseMercatorRaw),
35261 m.center = function(_) {
35262 return arguments.length ? center([-_[1], _[0]]) : (_ = center(), [_[1], -_[0]]);
35265 m.rotate = function(_) {
35266 return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 : 90]) : (_ = rotate(), [_[0], _[1], _[2] - 90]);
35269 return rotate([0, 0, 90])
35275 var index$1 = Object.freeze({
35277 bisect: bisectRight,
35278 bisectRight: bisectRight,
35279 bisectLeft: bisectLeft,
35280 ascending: ascending,
35281 bisector: bisector,
35282 descending: descending,
35283 deviation: deviation,
35285 histogram: histogram,
35286 thresholdFreedmanDiaconis: freedmanDiaconis,
35287 thresholdScott: scott,
35288 thresholdSturges: sturges,
35296 quantile: threshold,
35302 tickStep: tickStep,
35303 transpose: transpose,
35304 variance: variance,
35312 randomUniform: uniform,
35313 randomNormal: normal,
35314 randomLogNormal: logNormal,
35315 randomBates: bates,
35316 randomIrwinHall: irwinHall,
35317 randomExponential: exponential,
35318 easeLinear: linear,
35319 easeQuad: quadInOut,
35320 easeQuadIn: quadIn,
35321 easeQuadOut: quadOut,
35322 easeQuadInOut: quadInOut,
35323 easeCubic: cubicInOut,
35324 easeCubicIn: cubicIn,
35325 easeCubicOut: cubicOut,
35326 easeCubicInOut: cubicInOut,
35327 easePoly: polyInOut,
35328 easePolyIn: polyIn,
35329 easePolyOut: polyOut,
35330 easePolyInOut: polyInOut,
35333 easeSinOut: sinOut,
35334 easeSinInOut: sinInOut,
35337 easeExpOut: expOut,
35338 easeExpInOut: expInOut,
35339 easeCircle: circleInOut,
35340 easeCircleIn: circleIn,
35341 easeCircleOut: circleOut,
35342 easeCircleInOut: circleInOut,
35343 easeBounce: bounceOut,
35344 easeBounceIn: bounceIn,
35345 easeBounceOut: bounceOut,
35346 easeBounceInOut: bounceInOut,
35347 easeBack: backInOut,
35348 easeBackIn: backIn,
35349 easeBackOut: backOut,
35350 easeBackInOut: backInOut,
35351 easeElastic: elasticOut,
35352 easeElasticIn: elasticIn,
35353 easeElasticOut: elasticOut,
35354 easeElasticInOut: elasticInOut,
35355 polygonArea: d3polygonArea,
35356 polygonCentroid: d3polygonCentroid,
35357 polygonHull: d3polygonHull,
35358 polygonContains: contains,
35359 polygonLength: length$1,
35361 quadtree: quadtree,
35367 radialArea: radialArea,
35368 radialLine: radialLine$1,
35371 symbolCircle: circle,
35372 symbolCross: cross$1,
35373 symbolDiamond: diamond,
35374 symbolSquare: square,
35376 symbolTriangle: triangle,
35378 curveBasisClosed: basisClosed,
35379 curveBasisOpen: basisOpen,
35381 curveBundle: bundle,
35382 curveCardinalClosed: cardinalClosed,
35383 curveCardinalOpen: cardinalOpen,
35384 curveCardinal: cardinal,
35385 curveCatmullRomClosed: catmullRomClosed,
35386 curveCatmullRomOpen: catmullRomOpen,
35387 curveCatmullRom: catmullRom,
35388 curveLinearClosed: linearClosed,
35389 curveLinear: curveLinear,
35390 curveMonotoneX: monotoneX,
35391 curveMonotoneY: monotoneY,
35392 curveNatural: natural,
35394 curveStepAfter: stepAfter,
35395 curveStepBefore: stepBefore,
35397 stackOffsetExpand: expand,
35398 stackOffsetNone: none,
35399 stackOffsetSilhouette: silhouette,
35400 stackOffsetWiggle: wiggle,
35401 stackOrderAscending: ascending$1,
35402 stackOrderDescending: descending$2,
35403 stackOrderInsideOut: insideOut,
35404 stackOrderNone: none$1,
35405 stackOrderReverse: reverse,
35411 cubehelix: cubehelix,
35412 interpolate: interpolate,
35413 interpolateArray: array$1,
35414 interpolateDate: date,
35415 interpolateNumber: interpolateNumber,
35416 interpolateObject: object,
35417 interpolateRound: interpolateRound,
35418 interpolateString: interpolateString,
35419 interpolateTransformCss: interpolateTransformCss,
35420 interpolateTransformSvg: interpolateTransformSvg,
35421 interpolateZoom: interpolateZoom,
35422 interpolateRgb: interpolateRgb,
35423 interpolateRgbBasis: rgbBasis,
35424 interpolateRgbBasisClosed: rgbBasisClosed,
35425 interpolateHsl: hsl$2,
35426 interpolateHslLong: hslLong,
35427 interpolateLab: lab$1,
35428 interpolateHcl: hcl$2,
35429 interpolateHclLong: hclLong,
35430 interpolateCubehelix: cubehelix$2,
35431 interpolateCubehelixLong: cubehelixLong,
35432 interpolateBasis: basis$2,
35433 interpolateBasisClosed: basisClosed$1,
35434 quantize: quantize,
35435 dispatch: dispatch,
35437 csvParse: csvParse,
35438 csvParseRows: csvParseRows,
35439 csvFormat: csvFormat,
35440 csvFormatRows: csvFormatRows,
35441 tsvParse: tsvParse,
35442 tsvParseRows: tsvParseRows,
35443 tsvFormat: tsvFormat,
35444 tsvFormatRows: tsvFormatRows,
35454 timerFlush: timerFlush,
35455 timeout: timeout$1,
35456 interval: interval$1,
35457 timeInterval: newInterval,
35458 timeMillisecond: millisecond,
35459 timeMilliseconds: milliseconds,
35460 timeSecond: second,
35461 timeSeconds: seconds,
35462 timeMinute: minute,
35463 timeMinutes: minutes,
35469 timeWeeks: sundays,
35470 timeSunday: sunday,
35471 timeSundays: sundays,
35472 timeMonday: monday,
35473 timeMondays: mondays,
35474 timeTuesday: tuesday,
35475 timeTuesdays: tuesdays,
35476 timeWednesday: wednesday,
35477 timeWednesdays: wednesdays,
35478 timeThursday: thursday,
35479 timeThursdays: thursdays,
35480 timeFriday: friday,
35481 timeFridays: fridays,
35482 timeSaturday: saturday,
35483 timeSaturdays: saturdays,
35485 timeMonths: months,
35488 utcMillisecond: millisecond,
35489 utcMilliseconds: milliseconds,
35491 utcSeconds: seconds,
35492 utcMinute: utcMinute,
35493 utcMinutes: utcMinutes,
35495 utcHours: utcHours,
35498 utcWeek: utcSunday,
35499 utcWeeks: utcSundays,
35500 utcSunday: utcSunday,
35501 utcSundays: utcSundays,
35502 utcMonday: utcMonday,
35503 utcMondays: utcMondays,
35504 utcTuesday: utcTuesday,
35505 utcTuesdays: utcTuesdays,
35506 utcWednesday: utcWednesday,
35507 utcWednesdays: utcWednesdays,
35508 utcThursday: utcThursday,
35509 utcThursdays: utcThursdays,
35510 utcFriday: utcFriday,
35511 utcFridays: utcFridays,
35512 utcSaturday: utcSaturday,
35513 utcSaturdays: utcSaturdays,
35514 utcMonth: utcMonth,
35515 utcMonths: utcMonths,
35517 utcYears: utcYears,
35518 get format () { return format; },
35519 get formatPrefix () { return formatPrefix; },
35520 formatLocale: formatLocale,
35521 formatDefaultLocale: defaultLocale,
35522 formatSpecifier: formatSpecifier,
35523 precisionFixed: precisionFixed,
35524 precisionPrefix: precisionPrefix,
35525 precisionRound: precisionRound,
35526 get timeFormat () { return timeFormat; },
35527 get timeParse () { return timeParse; },
35528 get utcFormat () { return utcFormat; },
35529 get utcParse () { return utcParse; },
35530 isoFormat: formatIso,
35531 isoParse: parseIso,
35532 timeFormatLocale: formatLocale$1,
35533 timeFormatDefaultLocale: defaultLocale$1,
35535 scalePoint: point$4,
35536 scaleIdentity: identity$4,
35537 scaleLinear: linear$2,
35539 scaleOrdinal: ordinal,
35540 scaleImplicit: implicit,
35543 scaleQuantile: quantile$$1,
35544 scaleQuantize: quantize$1,
35545 scaleThreshold: threshold$1,
35548 schemeCategory10: category10,
35549 schemeCategory20b: category20b,
35550 schemeCategory20c: category20c,
35551 schemeCategory20: category20,
35552 scaleSequential: sequential,
35553 interpolateCubehelixDefault: cubehelix$3,
35554 interpolateRainbow: rainbow$1,
35555 interpolateWarm: warm,
35556 interpolateCool: cool,
35557 interpolateViridis: viridis,
35558 interpolateMagma: magma,
35559 interpolateInferno: inferno,
35560 interpolatePlasma: plasma,
35562 customEvent: customEvent,
35563 get event () { return event; },
35565 matcher: matcher$1,
35567 namespace: namespace,
35568 namespaces: namespaces,
35570 selectAll: selectAll,
35571 selection: selection,
35572 selector: selector,
35573 selectorAll: selectorAll,
35578 interrupt: interrupt,
35579 transition: transition,
35581 axisRight: axisRight,
35582 axisBottom: axisBottom,
35583 axisLeft: axisLeft,
35585 hierarchy: hierarchy,
35587 packSiblings: siblings,
35588 packEnclose: enclose,
35589 partition: partition,
35590 stratify: stratify,
35593 treemapBinary: binary,
35594 treemapDice: treemapDice,
35595 treemapSlice: treemapSlice,
35596 treemapSliceDice: sliceDice,
35597 treemapSquarify: squarify,
35598 treemapResquarify: resquarify,
35599 forceCenter: center$1,
35600 forceCollide: collide,
35602 forceManyBody: manyBody,
35603 forceSimulation: simulation,
35607 dragDisable: dragDisable,
35608 dragEnable: yesdrag,
35611 zoomIdentity: identity$6,
35612 zoomTransform: transform,
35616 brushSelection: brushSelection,
35620 geoAlbersUsa: albersUsa,
35622 geoAzimuthalEqualArea: azimuthalEqualArea,
35623 geoAzimuthalEqualAreaRaw: azimuthalEqualAreaRaw,
35624 geoAzimuthalEquidistant: azimuthalEquidistant,
35625 geoAzimuthalEquidistantRaw: azimuthalEquidistantRaw,
35627 geoCentroid: d3GeoCentroid,
35628 geoCircle: circle$1,
35629 geoClipExtent: extent$1,
35630 geoConicConformal: conicConformal,
35631 geoConicConformalRaw: conicConformalRaw,
35632 geoConicEqualArea: conicEqualArea,
35633 geoConicEqualAreaRaw: conicEqualAreaRaw,
35634 geoConicEquidistant: conicEquidistant,
35635 geoConicEquidistantRaw: conicEquidistantRaw,
35636 geoDistance: distance,
35637 geoEquirectangular: equirectangular,
35638 geoEquirectangularRaw: equirectangularRaw,
35639 geoGnomonic: gnomonic,
35640 geoGnomonicRaw: gnomonicRaw,
35641 geoGraticule: graticule,
35642 geoGraticule10: graticule10,
35643 geoIdentity: identity$8,
35644 geoInterpolate: interpolate$2,
35645 geoLength: d3GeoLength,
35646 geoMercator: mercator,
35647 geoMercatorRaw: mercatorRaw,
35648 geoOrthographic: orthographic,
35649 geoOrthographicRaw: orthographicRaw,
35651 geoProjection: projection,
35652 geoProjectionMutator: projectionMutator,
35653 geoRotation: rotation,
35654 geoStereographic: stereographic,
35655 geoStereographicRaw: stereographicRaw,
35656 geoStream: geoStream,
35657 geoTransform: transform$1,
35658 geoTransverseMercator: transverseMercator,
35659 geoTransverseMercatorRaw: transverseMercatorRaw
35663 Bypasses features of D3's default projection stream pipeline that are unnecessary:
35664 * Antimeridian clipping
35665 * Spherical rotation
35668 function geoRawMercator() {
35669 var project = mercatorRaw,
35670 k = 512 / Math.PI, // scale
35671 x = 0, y = 0, // translate
35672 clipExtent = [[0, 0], [0, 0]];
35675 function projection(point) {
35676 point = project(point[0] * Math.PI / 180, point[1] * Math.PI / 180);
35677 return [point[0] * k + x, y - point[1] * k];
35681 projection.invert = function(point) {
35682 point = project.invert((point[0] - x) / k, (y - point[1]) / k);
35683 return point && [point[0] * 180 / Math.PI, point[1] * 180 / Math.PI];
35687 projection.scale = function(_) {
35688 if (!arguments.length) return k;
35694 projection.translate = function(_) {
35695 if (!arguments.length) return [x, y];
35702 projection.clipExtent = function(_) {
35703 if (!arguments.length) return clipExtent;
35709 projection.transform = function(_) {
35710 if (!arguments.length) return identity$6.translate(x, y).scale(k);
35718 projection.stream = transform$1({
35719 point: function(x, y) {
35720 x = projection([x, y]);
35721 this.stream.point(x[0], x[1]);
35729 function geoRoundCoords(c) {
35730 return [Math.floor(c[0]), Math.floor(c[1])];
35734 function geoInterp(p1, p2, t) {
35735 return [p1[0] + (p2[0] - p1[0]) * t,
35736 p1[1] + (p2[1] - p1[1]) * t];
35740 // 2D cross product of OA and OB vectors, i.e. z-component of their 3D cross product.
35741 // Returns a positive value, if OAB makes a counter-clockwise turn,
35742 // negative for clockwise turn, and zero if the points are collinear.
35743 function geoCross(o, a, b) {
35744 return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]);
35748 // http://jsperf.com/id-dist-optimization
35749 function geoEuclideanDistance(a, b) {
35750 var x = a[0] - b[0], y = a[1] - b[1];
35751 return Math.sqrt((x * x) + (y * y));
35755 // using WGS84 polar radius (6356752.314245179 m)
35756 // const = 2 * PI * r / 360
35757 function geoLatToMeters(dLat) {
35758 return dLat * 110946.257617;
35762 // using WGS84 equatorial radius (6378137.0 m)
35763 // const = 2 * PI * r / 360
35764 function geoLonToMeters(dLon, atLat) {
35765 return Math.abs(atLat) >= 90 ? 0 :
35766 dLon * 111319.490793 * Math.abs(Math.cos(atLat * (Math.PI/180)));
35770 // using WGS84 polar radius (6356752.314245179 m)
35771 // const = 2 * PI * r / 360
35772 function geoMetersToLat(m) {
35773 return m / 110946.257617;
35777 // using WGS84 equatorial radius (6378137.0 m)
35778 // const = 2 * PI * r / 360
35779 function geoMetersToLon(m, atLat) {
35780 return Math.abs(atLat) >= 90 ? 0 :
35781 m / 111319.490793 / Math.abs(Math.cos(atLat * (Math.PI/180)));
35785 function geoOffsetToMeters(offset) {
35786 var equatRadius = 6356752.314245179,
35787 polarRadius = 6378137.0,
35791 offset[0] * 2 * Math.PI * equatRadius / tileSize,
35792 -offset[1] * 2 * Math.PI * polarRadius / tileSize
35797 function geoMetersToOffset(meters) {
35798 var equatRadius = 6356752.314245179,
35799 polarRadius = 6378137.0,
35803 meters[0] * tileSize / (2 * Math.PI * equatRadius),
35804 -meters[1] * tileSize / (2 * Math.PI * polarRadius)
35809 // Equirectangular approximation of spherical distances on Earth
35810 function geoSphericalDistance(a, b) {
35811 var x = geoLonToMeters(a[0] - b[0], (a[1] + b[1]) / 2),
35812 y = geoLatToMeters(a[1] - b[1]);
35813 return Math.sqrt((x * x) + (y * y));
35817 function geoEdgeEqual(a, b) {
35818 return (a[0] === b[0] && a[1] === b[1]) ||
35819 (a[0] === b[1] && a[1] === b[0]);
35823 // Return the counterclockwise angle in the range (-pi, pi)
35824 // between the positive X axis and the line intersecting a and b.
35825 function geoAngle(a, b, projection) {
35826 a = projection(a.loc);
35827 b = projection(b.loc);
35828 return Math.atan2(b[1] - a[1], b[0] - a[0]);
35832 // Choose the edge with the minimal distance from `point` to its orthogonal
35833 // projection onto that edge, if such a projection exists, or the distance to
35834 // the closest vertex on that edge. Returns an object with the `index` of the
35835 // chosen edge, the chosen `loc` on that edge, and the `distance` to to it.
35836 function geoChooseEdge(nodes, point, projection) {
35837 var dist = geoEuclideanDistance,
35838 points = nodes.map(function(n) { return projection(n.loc); }),
35842 function dot(p, q) {
35843 return p[0] * q[0] + p[1] * q[1];
35846 for (var i = 0; i < points.length - 1; i++) {
35848 s = [points[i + 1][0] - o[0],
35849 points[i + 1][1] - o[1]],
35850 v = [point[0] - o[0],
35852 proj = dot(v, s) / dot(s, s),
35857 } else if (proj > 1) {
35860 p = [o[0] + proj * s[0], o[1] + proj * s[1]];
35863 var d = dist(p, point);
35867 loc = projection.invert(p);
35879 // Return the intersection point of 2 line segments.
35880 // From https://github.com/pgkelley4/line-segments-intersect
35881 // This uses the vector cross product approach described below:
35882 // http://stackoverflow.com/a/565282/786339
35883 function geoLineIntersection(a, b) {
35884 function subtractPoints(point1, point2) {
35885 return [point1[0] - point2[0], point1[1] - point2[1]];
35887 function crossProduct(point1, point2) {
35888 return point1[0] * point2[1] - point1[1] * point2[0];
35891 var p = [a[0][0], a[0][1]],
35892 p2 = [a[1][0], a[1][1]],
35893 q = [b[0][0], b[0][1]],
35894 q2 = [b[1][0], b[1][1]],
35895 r = subtractPoints(p2, p),
35896 s = subtractPoints(q2, q),
35897 uNumerator = crossProduct(subtractPoints(q, p), r),
35898 denominator = crossProduct(r, s);
35900 if (uNumerator && denominator) {
35901 var u = uNumerator / denominator,
35902 t = crossProduct(subtractPoints(q, p), s) / denominator;
35904 if ((t >= 0) && (t <= 1) && (u >= 0) && (u <= 1)) {
35905 return geoInterp(p, p2, t);
35913 function geoPathIntersections(path1, path2) {
35914 var intersections = [];
35915 for (var i = 0; i < path1.length - 1; i++) {
35916 for (var j = 0; j < path2.length - 1; j++) {
35917 var a = [ path1[i], path1[i+1] ],
35918 b = [ path2[j], path2[j+1] ],
35919 hit = geoLineIntersection(a, b);
35920 if (hit) intersections.push(hit);
35923 return intersections;
35927 // Return whether point is contained in polygon.
35929 // `point` should be a 2-item array of coordinates.
35930 // `polygon` should be an array of 2-item arrays of coordinates.
35932 // From https://github.com/substack/point-in-polygon.
35933 // ray-casting algorithm based on
35934 // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
35936 function geoPointInPolygon(point, polygon) {
35941 for (var i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
35942 var xi = polygon[i][0], yi = polygon[i][1];
35943 var xj = polygon[j][0], yj = polygon[j][1];
35945 var intersect = ((yi > y) !== (yj > y)) &&
35946 (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
35947 if (intersect) inside = !inside;
35954 function geoPolygonContainsPolygon(outer, inner) {
35955 return lodash.every(inner, function(point) {
35956 return geoPointInPolygon(point, outer);
35961 function geoPolygonIntersectsPolygon(outer, inner, checkSegments) {
35962 function testSegments(outer, inner) {
35963 for (var i = 0; i < outer.length - 1; i++) {
35964 for (var j = 0; j < inner.length - 1; j++) {
35965 var a = [ outer[i], outer[i+1] ],
35966 b = [ inner[j], inner[j+1] ];
35967 if (geoLineIntersection(a, b)) return true;
35973 function testPoints(outer, inner) {
35974 return lodash.some(inner, function(point) {
35975 return geoPointInPolygon(point, outer);
35979 return testPoints(outer, inner) || (!!checkSegments && testSegments(outer, inner));
35983 function geoPathLength(path) {
35985 for (var i = 0; i < path.length - 1; i++) {
35986 length += geoEuclideanDistance(path[i], path[i + 1]);
35991 function osmNode() {
35992 if (!(this instanceof osmNode)) {
35993 return (new osmNode()).initialize(arguments);
35994 } else if (arguments.length) {
35995 this.initialize(arguments);
35999 osmEntity$$1.node = osmNode;
36001 osmNode.prototype = Object.create(osmEntity$$1.prototype);
36003 lodash.extend(osmNode.prototype, {
36008 extent: function() {
36009 return new geoExtent$$1(this.loc);
36013 geometry: function(graph) {
36014 return graph.transient(this, 'geometry', function() {
36015 return graph.isPoi(this) ? 'point' : 'vertex';
36020 move: function(loc) {
36021 return this.update({loc: loc});
36025 isIntersection: function(resolver) {
36026 return resolver.transient(this, 'isIntersection', function() {
36027 return resolver.parentWays(this).filter(function(parent) {
36028 return (parent.tags.highway ||
36029 parent.tags.waterway ||
36030 parent.tags.railway ||
36031 parent.tags.aeroway) &&
36032 parent.geometry(resolver) === 'line';
36038 isHighwayIntersection: function(resolver) {
36039 return resolver.transient(this, 'isHighwayIntersection', function() {
36040 return resolver.parentWays(this).filter(function(parent) {
36041 return parent.tags.highway && parent.geometry(resolver) === 'line';
36047 isOnAddressLine: function(resolver) {
36048 return resolver.transient(this, 'isOnAddressLine', function() {
36049 return resolver.parentWays(this).filter(function(parent) {
36050 return parent.tags.hasOwnProperty('addr:interpolation') &&
36051 parent.geometry(resolver) === 'line';
36057 asJXON: function(changeset_id) {
36060 '@id': this.osmId(),
36061 '@lon': this.loc[0],
36062 '@lat': this.loc[1],
36063 '@version': (this.version || 0),
36064 tag: lodash.map(this.tags, function(v, k) {
36065 return { keyAttributes: { k: k, v: v } };
36069 if (changeset_id) r.node['@changeset'] = changeset_id;
36074 asGeoJSON: function() {
36077 coordinates: this.loc
36083 Order the nodes of a way in reverse order and reverse any direction dependent tags
36084 other than `oneway`. (We assume that correcting a backwards oneway is the primary
36085 reason for reversing a way.)
36087 The following transforms are performed:
36090 *:right=* ⟺ *:left=*
36091 *:forward=* ⟺ *:backward=*
36092 direction=up ⟺ direction=down
36093 incline=up ⟺ incline=down
36097 role=forward ⟺ role=backward
36098 role=north ⟺ role=south
36099 role=east ⟺ role=west
36101 In addition, numeric-valued `incline` tags are negated.
36103 The JOSM implementation was used as a guide, but transformations that were of unclear benefit
36104 or adjusted tags that don't seem to be used in practice were omitted.
36106 Also, each node on the way is examined for its own tags and the following transformations are performed
36107 in order to ensure associated nodes (eg a Stop Sign) is also reversed
36110 direction=forward ⟺ direction=backward
36111 direction=left ⟺ direction=right
36112 *:forward=* ⟺ *:backward=*
36113 *:left=* ⟺ *:right=*
36116 http://wiki.openstreetmap.org/wiki/Forward_%26_backward,_left_%26_right
36117 http://wiki.openstreetmap.org/wiki/Key:direction#Steps
36118 http://wiki.openstreetmap.org/wiki/Key:incline
36119 http://wiki.openstreetmap.org/wiki/Route#Members
36120 http://josm.openstreetmap.de/browser/josm/trunk/src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java
36121 http://wiki.openstreetmap.org/wiki/Tag:highway%3Dstop
36122 http://wiki.openstreetmap.org/wiki/Key:traffic_sign#On_a_way_or_area
36124 function actionReverse(wayId, options) {
36125 var replacements = [
36126 [/:right$/, ':left'], [/:left$/, ':right'],
36127 [/:forward$/, ':backward'], [/:backward$/, ':forward']
36129 numeric = /^([+\-]?)(?=[\d.])/,
36131 forward: 'backward',
36132 backward: 'forward',
36140 function reverseKey(key) {
36141 for (var i = 0; i < replacements.length; ++i) {
36142 var replacement = replacements[i];
36143 if (replacement[0].test(key)) {
36144 return key.replace(replacement[0], replacement[1]);
36151 function reverseValue(key, value) {
36152 if (key === 'incline' && numeric.test(value)) {
36153 return value.replace(numeric, function(_, sign) { return sign === '-' ? '' : '-'; });
36154 } else if (key === 'incline' || key === 'direction') {
36155 return {up: 'down', down: 'up'}[value] || value;
36156 } else if (options && options.reverseOneway && key === 'oneway') {
36157 return {yes: '-1', '1': '-1', '-1': 'yes'}[value] || value;
36159 return {left: 'right', right: 'left'}[value] || value;
36164 function reverseDirectionTags(node) {
36165 // Update the direction based tags as appropriate then return an updated node
36166 return node.update({tags: lodash.transform(node.tags, function(acc, tagValue, tagKey) {
36167 // See if this is a direction tag and reverse (or use existing value if not recognised)
36168 if (tagKey === 'direction') {
36169 acc[tagKey] = {forward: 'backward', backward: 'forward', left: 'right', right: 'left'}[tagValue] || tagValue;
36171 // Use the reverseKey method to cater for situations such as traffic_sign:forward=stop
36172 // This will pass through other tags unchanged
36173 acc[reverseKey(tagKey)] = tagValue;
36180 function reverseTagsOnNodes(graph, nodeIds) {
36181 // Reverse the direction of appropriate tags attached to the nodes (#3076)
36182 return lodash(nodeIds)
36183 // Get each node from the graph
36184 .map(function(nodeId) { return graph.entity(nodeId);})
36185 // Check tags on the node, if there aren't any, we can skip
36186 .filter(function(existingNode) { return existingNode.tags !== undefined;})
36187 // Get a new version of each node with the appropriate tags reversed
36188 .map(function(existingNode) { return reverseDirectionTags(existingNode);})
36189 // Chain together consecutive updates to the graph for each updated node and return
36190 .reduce(function (accGraph, value) { return accGraph.replace(value); }, graph);
36194 return function(graph) {
36195 var way = graph.entity(wayId),
36196 nodes = way.nodes.slice().reverse(),
36197 tags = {}, key, role;
36199 for (key in way.tags) {
36200 tags[reverseKey(key)] = reverseValue(key, way.tags[key]);
36203 graph.parentRelations(way).forEach(function(relation) {
36204 relation.members.forEach(function(member, index) {
36205 if (member.id === way.id && (role = roleReversals[member.role])) {
36206 relation = relation.updateMember({role: role}, index);
36207 graph = graph.replace(relation);
36212 // Reverse any associated directions on nodes on the way and then replace
36213 // the way itself with the reversed node ids and updated way tags
36214 return reverseTagsOnNodes(graph, nodes).replace(way.update({nodes: nodes, tags: tags}));
36218 // For fixing up rendering of multipolygons with tags on the outer member.
36219 // https://github.com/openstreetmap/iD/issues/613
36220 function osmIsSimpleMultipolygonOuterMember(entity, graph) {
36221 if (entity.type !== 'way')
36224 var parents = graph.parentRelations(entity);
36225 if (parents.length !== 1)
36228 var parent = parents[0];
36229 if (!parent.isMultipolygon() || Object.keys(parent.tags).length > 1)
36232 var members = parent.members, member;
36233 for (var i = 0; i < members.length; i++) {
36234 member = members[i];
36235 if (member.id === entity.id && member.role && member.role !== 'outer')
36236 return false; // Not outer member
36237 if (member.id !== entity.id && (!member.role || member.role === 'outer'))
36238 return false; // Not a simple multipolygon
36245 function osmSimpleMultipolygonOuterMember(entity, graph) {
36246 if (entity.type !== 'way')
36249 var parents = graph.parentRelations(entity);
36250 if (parents.length !== 1)
36253 var parent = parents[0];
36254 if (!parent.isMultipolygon() || Object.keys(parent.tags).length > 1)
36257 var members = parent.members, member, outerMember;
36258 for (var i = 0; i < members.length; i++) {
36259 member = members[i];
36260 if (!member.role || member.role === 'outer') {
36262 return false; // Not a simple multipolygon
36263 outerMember = member;
36267 return outerMember && graph.hasEntity(outerMember.id);
36271 // Join `array` into sequences of connecting ways.
36273 // Segments which share identical start/end nodes will, as much as possible,
36274 // be connected with each other.
36276 // The return value is a nested array. Each constituent array contains elements
36277 // of `array` which have been determined to connect. Each consitituent array
36278 // also has a `nodes` property whose value is an ordered array of member nodes,
36279 // with appropriate order reversal and start/end coordinate de-duplication.
36281 // Members of `array` must have, at minimum, `type` and `id` properties.
36282 // Thus either an array of `osmWay`s or a relation member array may be
36285 // If an member has a `tags` property, its tags will be reversed via
36286 // `actionReverse` in the output.
36288 // Incomplete members (those for which `graph.hasEntity(element.id)` returns
36289 // false) and non-way members are ignored.
36291 function osmJoinWays(array, graph) {
36292 var joined = [], member, current, nodes, first, last, i, how, what;
36294 array = array.filter(function(member) {
36295 return member.type === 'way' && graph.hasEntity(member.id);
36298 function resolve(member) {
36299 return graph.childNodes(graph.entity(member.id));
36302 function reverse(member) {
36303 return member.tags ? actionReverse(member.id, { reverseOneway: true })(graph).entity(member.id) : member;
36306 while (array.length) {
36307 member = array.shift();
36308 current = [member];
36309 current.nodes = nodes = resolve(member).slice();
36310 joined.push(current);
36312 while (array.length && lodash.first(nodes) !== lodash.last(nodes)) {
36313 first = lodash.first(nodes);
36314 last = lodash.last(nodes);
36316 for (i = 0; i < array.length; i++) {
36318 what = resolve(member);
36320 if (last === lodash.first(what)) {
36322 what = what.slice(1);
36324 } else if (last === lodash.last(what)) {
36326 what = what.slice(0, -1).reverse();
36327 member = reverse(member);
36329 } else if (first === lodash.last(what)) {
36330 how = nodes.unshift;
36331 what = what.slice(0, -1);
36333 } else if (first === lodash.first(what)) {
36334 how = nodes.unshift;
36335 what = what.slice(1).reverse();
36336 member = reverse(member);
36344 break; // No more joinable ways.
36346 how.apply(current, [member]);
36347 how.apply(nodes, what);
36349 array.splice(i, 1);
36356 function osmRelation() {
36357 if (!(this instanceof osmRelation)) {
36358 return (new osmRelation()).initialize(arguments);
36359 } else if (arguments.length) {
36360 this.initialize(arguments);
36365 osmEntity$$1.relation = osmRelation;
36367 osmRelation.prototype = Object.create(osmEntity$$1.prototype);
36370 osmRelation.creationOrder = function(a, b) {
36371 var aId = parseInt(osmEntity$$1.id.toOSM(a.id), 10);
36372 var bId = parseInt(osmEntity$$1.id.toOSM(b.id), 10);
36374 if (aId < 0 || bId < 0) return aId - bId;
36379 lodash.extend(osmRelation.prototype, {
36384 copy: function(resolver, copies) {
36385 if (copies[this.id])
36386 return copies[this.id];
36388 var copy = osmEntity$$1.prototype.copy.call(this, resolver, copies);
36390 var members = this.members.map(function(member) {
36391 return lodash.extend({}, member, { id: resolver.entity(member.id).copy(resolver, copies).id });
36394 copy = copy.update({members: members});
36395 copies[this.id] = copy;
36401 extent: function(resolver, memo) {
36402 return resolver.transient(this, 'extent', function() {
36403 if (memo && memo[this.id]) return geoExtent$$1();
36405 memo[this.id] = true;
36407 var extent$$1 = geoExtent$$1();
36408 for (var i = 0; i < this.members.length; i++) {
36409 var member = resolver.hasEntity(this.members[i].id);
36411 extent$$1._extend(member.extent(resolver, memo));
36419 geometry: function(graph) {
36420 return graph.transient(this, 'geometry', function() {
36421 return this.isMultipolygon() ? 'area' : 'relation';
36426 isDegenerate: function() {
36427 return this.members.length === 0;
36431 // Return an array of members, each extended with an 'index' property whose value
36432 // is the member index.
36433 indexedMembers: function() {
36434 var result = new Array(this.members.length);
36435 for (var i = 0; i < this.members.length; i++) {
36436 result[i] = lodash.extend({}, this.members[i], {index: i});
36442 // Return the first member with the given role. A copy of the member object
36443 // is returned, extended with an 'index' property whose value is the member index.
36444 memberByRole: function(role) {
36445 for (var i = 0; i < this.members.length; i++) {
36446 if (this.members[i].role === role) {
36447 return lodash.extend({}, this.members[i], {index: i});
36453 // Return the first member with the given id. A copy of the member object
36454 // is returned, extended with an 'index' property whose value is the member index.
36455 memberById: function(id) {
36456 for (var i = 0; i < this.members.length; i++) {
36457 if (this.members[i].id === id) {
36458 return lodash.extend({}, this.members[i], {index: i});
36464 // Return the first member with the given id and role. A copy of the member object
36465 // is returned, extended with an 'index' property whose value is the member index.
36466 memberByIdAndRole: function(id, role) {
36467 for (var i = 0; i < this.members.length; i++) {
36468 if (this.members[i].id === id && this.members[i].role === role) {
36469 return lodash.extend({}, this.members[i], {index: i});
36475 addMember: function(member, index) {
36476 var members = this.members.slice();
36477 members.splice(index === undefined ? members.length : index, 0, member);
36478 return this.update({members: members});
36482 updateMember: function(member, index) {
36483 var members = this.members.slice();
36484 members.splice(index, 1, lodash.extend({}, members[index], member));
36485 return this.update({members: members});
36489 removeMember: function(index) {
36490 var members = this.members.slice();
36491 members.splice(index, 1);
36492 return this.update({members: members});
36496 removeMembersWithID: function(id) {
36497 var members = lodash.reject(this.members, function(m) { return m.id === id; });
36498 return this.update({members: members});
36502 // Wherever a member appears with id `needle.id`, replace it with a member
36503 // with id `replacement.id`, type `replacement.type`, and the original role,
36504 // unless a member already exists with that id and role. Return an updated
36506 replaceMember: function(needle, replacement) {
36507 if (!this.memberById(needle.id))
36512 for (var i = 0; i < this.members.length; i++) {
36513 var member = this.members[i];
36514 if (member.id !== needle.id) {
36515 members.push(member);
36516 } else if (!this.memberByIdAndRole(replacement.id, member.role)) {
36517 members.push({id: replacement.id, type: replacement.type, role: member.role});
36521 return this.update({members: members});
36525 asJXON: function(changeset_id) {
36528 '@id': this.osmId(),
36529 '@version': this.version || 0,
36530 member: lodash.map(this.members, function(member) {
36535 ref: osmEntity$$1.id.toOSM(member.id)
36539 tag: lodash.map(this.tags, function(v, k) {
36540 return { keyAttributes: { k: k, v: v } };
36544 if (changeset_id) r.relation['@changeset'] = changeset_id;
36549 asGeoJSON: function(resolver) {
36550 return resolver.transient(this, 'GeoJSON', function () {
36551 if (this.isMultipolygon()) {
36553 type: 'MultiPolygon',
36554 coordinates: this.multipolygon(resolver)
36558 type: 'FeatureCollection',
36559 properties: this.tags,
36560 features: this.members.map(function (member) {
36561 return lodash.extend({role: member.role}, resolver.entity(member.id).asGeoJSON(resolver));
36569 area: function(resolver) {
36570 return resolver.transient(this, 'area', function() {
36571 return area$1(this.asGeoJSON(resolver));
36576 isMultipolygon: function() {
36577 return this.tags.type === 'multipolygon';
36581 isComplete: function(resolver) {
36582 for (var i = 0; i < this.members.length; i++) {
36583 if (!resolver.hasEntity(this.members[i].id)) {
36591 isRestriction: function() {
36592 return !!(this.tags.type && this.tags.type.match(/^restriction:?/));
36596 // Returns an array [A0, ... An], each Ai being an array of node arrays [Nds0, ... Ndsm],
36597 // where Nds0 is an outer ring and subsequent Ndsi's (if any i > 0) being inner rings.
36599 // This corresponds to the structure needed for rendering a multipolygon path using a
36600 // `evenodd` fill rule, as well as the structure of a GeoJSON MultiPolygon geometry.
36602 // In the case of invalid geometries, this function will still return a result which
36603 // includes the nodes of all way members, but some Nds may be unclosed and some inner
36604 // rings not matched with the intended outer ring.
36606 multipolygon: function(resolver) {
36607 var outers = this.members.filter(function(m) { return 'outer' === (m.role || 'outer'); }),
36608 inners = this.members.filter(function(m) { return 'inner' === m.role; });
36610 outers = osmJoinWays(outers, resolver);
36611 inners = osmJoinWays(inners, resolver);
36613 outers = outers.map(function(outer) { return lodash.map(outer.nodes, 'loc'); });
36614 inners = inners.map(function(inner) { return lodash.map(inner.nodes, 'loc'); });
36616 var result = outers.map(function(o) {
36617 // Heuristic for detecting counterclockwise winding order. Assumes
36618 // that OpenStreetMap polygons are not hemisphere-spanning.
36619 return [area$1({ type: 'Polygon', coordinates: [o] }) > 2 * Math.PI ? o.reverse() : o];
36622 function findOuter(inner) {
36625 for (o = 0; o < outers.length; o++) {
36627 if (geoPolygonContainsPolygon(outer, inner))
36631 for (o = 0; o < outers.length; o++) {
36633 if (geoPolygonIntersectsPolygon(outer, inner, false))
36638 for (var i = 0; i < inners.length; i++) {
36639 var inner = inners[i];
36641 if (area$1({ type: 'Polygon', coordinates: [inner] }) < 2 * Math.PI) {
36642 inner = inner.reverse();
36645 var o = findOuter(inners[i]);
36646 if (o !== undefined)
36647 result[o].push(inners[i]);
36649 result.push([inners[i]]); // Invalid geometry
36656 function osmLanes(entity) {
36657 if (entity.type !== 'way') return null;
36658 if (!entity.tags.highway) return null;
36660 var tags = entity.tags;
36661 var isOneWay = entity.isOneWay();
36662 var laneCount = getLaneCount(tags, isOneWay);
36663 var maxspeed = parseMaxspeed(tags);
36665 var laneDirections = parseLaneDirections(tags, isOneWay, laneCount);
36666 var forward = laneDirections.forward;
36667 var backward = laneDirections.backward;
36668 var bothways = laneDirections.bothways;
36670 // parse the piped string 'x|y|z' format
36671 var turnLanes = {};
36672 turnLanes.unspecified = parseTurnLanes(tags['turn:lanes']);
36673 turnLanes.forward = parseTurnLanes(tags['turn:lanes:forward']);
36674 turnLanes.backward = parseTurnLanes(tags['turn:lanes:backward']);
36676 var maxspeedLanes = {};
36677 maxspeedLanes.unspecified = parseMaxspeedLanes(tags['maxspeed:lanes'], maxspeed);
36678 maxspeedLanes.forward = parseMaxspeedLanes(tags['maxspeed:lanes:forward'], maxspeed);
36679 maxspeedLanes.backward = parseMaxspeedLanes(tags['maxspeed:lanes:backward'], maxspeed);
36682 psvLanes.unspecified = parseMiscLanes(tags['psv:lanes']);
36683 psvLanes.forward = parseMiscLanes(tags['psv:lanes:forward']);
36684 psvLanes.backward = parseMiscLanes(tags['psv:lanes:backward']);
36687 busLanes.unspecified = parseMiscLanes(tags['bus:lanes']);
36688 busLanes.forward = parseMiscLanes(tags['bus:lanes:forward']);
36689 busLanes.backward = parseMiscLanes(tags['bus:lanes:backward']);
36691 var taxiLanes = {};
36692 taxiLanes.unspecified = parseMiscLanes(tags['taxi:lanes']);
36693 taxiLanes.forward = parseMiscLanes(tags['taxi:lanes:forward']);
36694 taxiLanes.backward = parseMiscLanes(tags['taxi:lanes:backward']);
36697 hovLanes.unspecified = parseMiscLanes(tags['hov:lanes']);
36698 hovLanes.forward = parseMiscLanes(tags['hov:lanes:forward']);
36699 hovLanes.backward = parseMiscLanes(tags['hov:lanes:backward']);
36702 hgvLanes.unspecified = parseMiscLanes(tags['hgv:lanes']);
36703 hgvLanes.forward = parseMiscLanes(tags['hgv:lanes:forward']);
36704 hgvLanes.backward = parseMiscLanes(tags['hgv:lanes:backward']);
36706 var bicyclewayLanes = {};
36707 bicyclewayLanes.unspecified = parseBicycleWay(tags['bicycleway:lanes']);
36708 bicyclewayLanes.forward = parseBicycleWay(tags['bicycleway:lanes:forward']);
36709 bicyclewayLanes.backward = parseBicycleWay(tags['bicycleway:lanes:backward']);
36717 // map forward/backward/unspecified of each lane type to lanesObj
36718 mapToLanesObj(lanesObj, turnLanes, 'turnLane');
36719 mapToLanesObj(lanesObj, maxspeedLanes, 'maxspeed');
36720 mapToLanesObj(lanesObj, psvLanes, 'psv');
36721 mapToLanesObj(lanesObj, busLanes, 'bus');
36722 mapToLanesObj(lanesObj, taxiLanes, 'taxi');
36723 mapToLanesObj(lanesObj, hovLanes, 'hov');
36724 mapToLanesObj(lanesObj, hgvLanes, 'hgv');
36725 mapToLanesObj(lanesObj, bicyclewayLanes, 'bicycleway');
36732 backward: backward,
36733 bothways: bothways,
36734 turnLanes: turnLanes,
36735 maxspeed: maxspeed,
36736 maxspeedLanes: maxspeedLanes,
36737 psvLanes: psvLanes,
36738 busLanes: busLanes,
36739 taxiLanes: taxiLanes,
36740 hovLanes: hovLanes,
36741 hgvLanes: hgvLanes,
36742 bicyclewayLanes: bicyclewayLanes
36749 function getLaneCount(tags, isOneWay) {
36752 count = parseInt(tags.lanes, 10);
36759 switch (tags.highway) {
36762 count = isOneWay ? 2 : 4;
36765 count = isOneWay ? 1 : 2;
36773 function parseMaxspeed(tags) {
36774 var maxspeed = tags.maxspeed;
36775 if (lodash.isNumber(maxspeed)) return maxspeed;
36776 if (lodash.isString(maxspeed)) {
36777 maxspeed = maxspeed.match(/^([0-9][\.0-9]+?)(?:[ ]?(?:km\/h|kmh|kph|mph|knots))?$/g);
36778 if (!maxspeed) return;
36779 return parseInt(maxspeed, 10);
36784 function parseLaneDirections(tags, isOneWay, laneCount) {
36785 var forward = parseInt(tags['lanes:forward'], 10);
36786 var backward = parseInt(tags['lanes:backward'], 10);
36787 var bothways = parseInt(tags['lanes:both_ways'], 10) > 0 ? 1 : 0;
36789 if (parseInt(tags.oneway, 10) === -1) {
36792 backward = laneCount;
36794 else if (isOneWay) {
36795 forward = laneCount;
36799 else if (lodash.isNaN(forward) && lodash.isNaN(backward)) {
36800 backward = Math.floor((laneCount - bothways) / 2);
36801 forward = laneCount - bothways - backward;
36803 else if (lodash.isNaN(forward)) {
36804 if (backward > laneCount - bothways) {
36805 backward = laneCount - bothways;
36807 forward = laneCount - bothways - backward;
36809 else if (lodash.isNaN(backward)) {
36810 if (forward > laneCount - bothways) {
36811 forward = laneCount - bothways;
36813 backward = laneCount - bothways - forward;
36817 backward: backward,
36823 function parseTurnLanes(tag){
36826 var validValues = [
36827 'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right',
36828 'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none'
36831 return tag.split('|')
36832 .map(function (s) {
36833 if (s === '') s = 'none';
36834 return s.split(';')
36835 .map(function (d) {
36836 return validValues.indexOf(d) === -1 ? 'unknown': d;
36842 function parseMaxspeedLanes(tag, maxspeed) {
36845 return tag.split('|')
36846 .map(function (s) {
36847 if (s === 'none') return s;
36848 var m = parseInt(s, 10);
36849 if (s === '' || m === maxspeed) return null;
36850 return lodash.isNaN(m) ? 'unknown': m;
36855 function parseMiscLanes(tag) {
36858 var validValues = [
36859 'yes', 'no', 'designated'
36862 return tag.split('|')
36863 .map(function (s) {
36864 if (s === '') s = 'no';
36865 return validValues.indexOf(s) === -1 ? 'unknown': s;
36870 function parseBicycleWay(tag) {
36873 var validValues = [
36874 'yes', 'no', 'designated', 'lane'
36877 return tag.split('|')
36878 .map(function (s) {
36879 if (s === '') s = 'no';
36880 return validValues.indexOf(s) === -1 ? 'unknown': s;
36885 function mapToLanesObj(lanesObj, data, key) {
36886 if (data.forward) data.forward.forEach(function(l, i) {
36887 if (!lanesObj.forward[i]) lanesObj.forward[i] = {};
36888 lanesObj.forward[i][key] = l;
36890 if (data.backward) data.backward.forEach(function(l, i) {
36891 if (!lanesObj.backward[i]) lanesObj.backward[i] = {};
36892 lanesObj.backward[i][key] = l;
36894 if (data.unspecified) data.unspecified.forEach(function(l, i) {
36895 if (!lanesObj.unspecified[i]) lanesObj.unspecified[i] = {};
36896 lanesObj.unspecified[i][key] = l;
36900 var translations = Object.create(null);
36902 var currentLocale = 'en';
36903 var textDirection = 'ltr';
36905 function setLocale(_) {
36906 if (translations[_] !== undefined) {
36908 } else if (translations[_.split('-')[0]]) {
36909 currentLocale = _.split('-')[0];
36913 function addTranslation(id, value) {
36914 translations[id] = value;
36918 * Given a string identifier, try to find that string in the current
36919 * language, and return it.
36921 * @param {string} s string identifier
36922 * @returns {string?} locale string
36924 function t(s, o, loc) {
36925 loc = loc || currentLocale;
36927 var path = s.split('.').reverse();
36928 var rep = translations[loc];
36930 while (rep !== undefined && path.length) rep = rep[path.pop()];
36932 if (rep !== undefined) {
36933 if (o) for (var k in o) rep = rep.replace('{' + k + '}', o[k]);
36937 if (loc !== 'en') {
36938 return t(s, o, 'en');
36941 if (o && 'default' in o) {
36945 var missing = 'Missing ' + loc + ' translation: ' + s;
36946 if (typeof console !== 'undefined') console.error(missing); // eslint-disable-line
36952 * Given string 'ltr' or 'rtl', save that setting
36954 * @param {string} s ltr or rtl
36957 function setTextDirection(dir) {
36958 textDirection = dir;
36963 function utilDetect(force) {
36964 if (detected && !force) return detected;
36967 var ua = navigator.userAgent,
36970 m = ua.match(/(edge)\/?\s*(\.?\d+(\.\d+)*)/i); // Edge
36972 detected.browser = m[1];
36973 detected.version = m[2];
36975 if (!detected.browser) {
36976 m = ua.match(/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/i); // IE11
36978 detected.browser = 'msie';
36979 detected.version = m[1];
36982 if (!detected.browser) {
36983 m = ua.match(/(opr)\/?\s*(\.?\d+(\.\d+)*)/i); // Opera 15+
36985 detected.browser = 'Opera';
36986 detected.version = m[2];
36989 if (!detected.browser) {
36990 m = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
36992 detected.browser = m[1];
36993 detected.version = m[2];
36994 m = ua.match(/version\/([\.\d]+)/i);
36995 if (m !== null) detected.version = m[1];
36998 if (!detected.browser) {
36999 detected.browser = navigator.appName;
37000 detected.version = navigator.appVersion;
37003 // keep major.minor version only..
37004 detected.version = detected.version.split(/\W/).slice(0,2).join('.');
37006 if (detected.browser.toLowerCase() === 'msie') {
37007 detected.ie = true;
37008 detected.browser = 'Internet Explorer';
37009 detected.support = parseFloat(detected.version) >= 11;
37011 detected.ie = false;
37012 detected.support = true;
37015 // Added due to incomplete svg style support. See #715
37016 detected.opera = (detected.browser.toLowerCase() === 'opera' && parseFloat(detected.version) < 15 );
37018 detected.locale = (navigator.languages && navigator.languages.length)
37019 ? navigator.languages[0] : (navigator.language || navigator.userLanguage || 'en-US');
37021 // Loaded locale is stored in currentLocale
37022 // return that instead (except in the situation where 'en' might override 'en-US')
37023 var loadedLocale = currentLocale || 'en';
37024 if (loadedLocale !== 'en') {
37025 detected.locale = loadedLocale;
37028 // detect text direction
37029 var q = utilStringQs(window.location.hash.substring(1));
37030 if (['ar', 'fa', 'iw', 'he', 'dv'].indexOf(detected.locale.split('-')[0]) > -1 || q.hasOwnProperty('rtl')) {
37031 detected.textDirection = 'rtl';
37033 detected.textDirection = 'ltr';
37035 setTextDirection(detected.textDirection);
37037 detected.host = window.location && (window.location.origin + window.location.pathname);
37039 detected.filedrop = (window.FileReader && 'ondrop' in window);
37042 return navigator.userAgent.indexOf(x) !== -1;
37046 detected.os = 'win';
37047 detected.platform = 'Windows';
37049 else if (nav('Mac')) {
37050 detected.os = 'mac';
37051 detected.platform = 'Macintosh';
37053 else if (nav('X11') || nav('Linux')) {
37054 detected.os = 'linux';
37055 detected.platform = 'Linux';
37058 detected.os = 'win';
37059 detected.platform = 'Unknown';
37065 var remove$1 = removeDiacritics;
37067 var replacementList = [
37076 chars: "\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F",
37082 chars: "\u00C6\u01FC\u01E2",
37091 chars: "\uA738\uA73A",
37097 chars: "\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0181",
37100 chars: "\u24b8\uff23\uA73E\u1E08\u0106\u0043\u0108\u010A\u010C\u00C7\u0187\u023B",
37103 chars: "\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018A\u0189\u1D05\uA779",
37109 chars: "\u01F1\u01C4",
37112 chars: "\u01F2\u01C5",
37115 chars: "\u025B\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E\u1D07",
37118 chars: "\uA77C\u24BB\uFF26\u1E1E\u0191\uA77B",
37121 chars: "\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E\u0262",
37124 chars: "\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D",
37127 chars: "\u24BE\uFF29\xCC\xCD\xCE\u0128\u012A\u012C\u0130\xCF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197",
37130 chars: "\u24BF\uFF2A\u0134\u0248\u0237",
37133 chars: "\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2",
37136 chars: "\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780",
37145 chars: "\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C\u03FB",
37148 chars: "\uA7A4\u0220\u24C3\uFF2E\u01F8\u0143\xD1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u019D\uA790\u1D0E",
37157 chars: "\u24C4\uFF2F\xD2\xD3\xD4\u1ED2\u1ED0\u1ED6\u1ED4\xD5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\xD6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\xD8\u01FE\u0186\u019F\uA74A\uA74C",
37172 chars: "\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754",
37175 chars: "\u24C6\uFF31\uA756\uA758\u024A",
37178 chars: "\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782",
37181 chars: "\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784",
37184 chars: "\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786",
37193 chars: "\u24CA\uFF35\xD9\xDA\xDB\u0168\u1E78\u016A\u1E7A\u016C\xDC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244",
37196 chars: "\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245",
37202 chars: "\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72",
37205 chars: "\u24CD\uFF38\u1E8A\u1E8C",
37208 chars: "\u24CE\uFF39\u1EF2\xDD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE",
37211 chars: "\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762",
37214 chars: "\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250\u0251",
37220 chars: "\u00E6\u01FD\u01E3",
37229 chars: "\uA739\uA73B",
37235 chars: "\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253\u0182",
37238 chars: "\uFF43\u24D2\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184",
37241 chars: "\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\u018B\u13E7\u0501\uA7AA",
37247 chars: "\u01F3\u01C6",
37250 chars: "\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u01DD",
37253 chars: "\u24D5\uFF46\u1E1F\u0192",
37271 chars: "\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\uA77F\u1D79",
37274 chars: "\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265",
37280 chars: "\u24D8\uFF49\xEC\xED\xEE\u0129\u012B\u012D\xEF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131",
37283 chars: "\u24D9\uFF4A\u0135\u01F0\u0249",
37286 chars: "\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3",
37289 chars: "\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747\u026D",
37295 chars: "\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F",
37298 chars: "\u24DD\uFF4E\u01F9\u0144\xF1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5\u043B\u0509",
37304 chars: "\u24DE\uFF4F\xF2\xF3\xF4\u1ED3\u1ED1\u1ED7\u1ED5\xF5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\xF6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\xF8\u01FF\uA74B\uA74D\u0275\u0254\u1D11",
37319 chars: "\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755\u03C1",
37322 chars: "\u24E0\uFF51\u024B\uA757\uA759",
37325 chars: "\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783",
37328 chars: "\u24E2\uFF53\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B\u0282",
37334 chars: "\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787",
37343 chars: "\u24E4\uFF55\xF9\xFA\xFB\u0169\u1E79\u016B\u1E7B\u016D\xFC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289",
37346 chars: "\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C",
37352 chars: "\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73",
37355 chars: "\u24E7\uFF58\u1E8B\u1E8D",
37358 chars: "\u24E8\uFF59\u1EF3\xFD\u0177\u1EF9\u0233\u1E8F\xFF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF",
37361 chars: "\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763",
37365 var diacriticsMap = {};
37366 for (var i = 0; i < replacementList.length; i += 1) {
37367 var chars = replacementList[i].chars;
37368 for (var j = 0; j < chars.length; j += 1) {
37369 diacriticsMap[chars[j]] = replacementList[i].base;
37373 function removeDiacritics(str) {
37374 return str.replace(/[^\u0000-\u007e]/g, function(c) {
37375 return diacriticsMap[c] || c;
37379 function utilTagText(entity) {
37380 return entries(entity.tags).map(function(e) {
37381 return e.key + '=' + e.value;
37386 function utilEntitySelector(ids) {
37387 return ids.length ? '.' + ids.join(',.') : 'nothing';
37391 function utilEntityOrMemberSelector(ids, graph) {
37392 var s = utilEntitySelector(ids);
37394 ids.forEach(function(id) {
37395 var entity = graph.hasEntity(id);
37396 if (entity && entity.type === 'relation') {
37397 entity.members.forEach(function(member) {
37398 s += ',.' + member.id;
37407 function utilDisplayName(entity) {
37408 var localizedNameKey = 'name:' + utilDetect().locale.toLowerCase().split('-')[0],
37409 name = entity.tags[localizedNameKey] || entity.tags.name || '',
37410 network = entity.tags.cycle_network || entity.tags.network;
37411 if (!name && entity.tags.ref) {
37412 name = entity.tags.ref;
37414 name = network + ' ' + name;
37421 function utilDisplayType(id) {
37423 n: t('inspector.node'),
37424 w: t('inspector.way'),
37425 r: t('inspector.relation')
37430 function utilStringQs(str) {
37431 return str.split('&').reduce(function(obj, pair){
37432 var parts = pair.split('=');
37433 if (parts.length === 2) {
37434 obj[parts[0]] = (null === parts[1]) ? '' : decodeURIComponent(parts[1]);
37441 function utilQsString(obj, noencode) {
37442 function softEncode(s) {
37443 // encode everything except special characters used in certain hash parameters:
37444 // "/" in map states, ":", ",", {" and "}" in background
37445 return encodeURIComponent(s).replace(/(%2F|%3A|%2C|%7B|%7D)/g, decodeURIComponent);
37447 return Object.keys(obj).sort().map(function(key) {
37448 return encodeURIComponent(key) + '=' + (
37449 noencode ? softEncode(obj[key]) : encodeURIComponent(obj[key]));
37454 function utilPrefixDOMProperty(property) {
37455 var prefixes = ['webkit', 'ms', 'moz', 'o'],
37457 n = prefixes.length,
37463 property = property.substr(0, 1).toUpperCase() + property.substr(1);
37466 if (prefixes[i] + property in s)
37467 return prefixes[i] + property;
37473 function utilPrefixCSSProperty(property) {
37474 var prefixes = ['webkit', 'ms', 'Moz', 'O'],
37476 n = prefixes.length,
37477 s = document.body.style;
37479 if (property.toLowerCase() in s)
37480 return property.toLowerCase();
37483 if (prefixes[i] + property in s)
37484 return '-' + prefixes[i].toLowerCase() + property.replace(/([A-Z])/g, '-$1').toLowerCase();
37490 var transformProperty;
37491 function utilSetTransform(el, x, y, scale) {
37492 var prop = transformProperty = transformProperty || utilPrefixCSSProperty('Transform'),
37493 translate = utilDetect().opera ?
37494 'translate(' + x + 'px,' + y + 'px)' :
37495 'translate3d(' + x + 'px,' + y + 'px,0)';
37496 return el.style(prop, translate + (scale ? ' scale(' + scale + ')' : ''));
37500 // Calculates Levenshtein distance between two strings
37501 // see: https://en.wikipedia.org/wiki/Levenshtein_distance
37502 // first converts the strings to lowercase and replaces diacritic marks with ascii equilivants.
37503 function utilEditDistance(a, b) {
37504 a = remove$1(a.toLowerCase());
37505 b = remove$1(b.toLowerCase());
37506 if (a.length === 0) return b.length;
37507 if (b.length === 0) return a.length;
37509 for (var i = 0; i <= b.length; i++) { matrix[i] = [i]; }
37510 for (var j = 0; j <= a.length; j++) { matrix[0][j] = j; }
37511 for (i = 1; i <= b.length; i++) {
37512 for (j = 1; j <= a.length; j++) {
37513 if (b.charAt(i-1) === a.charAt(j-1)) {
37514 matrix[i][j] = matrix[i-1][j-1];
37516 matrix[i][j] = Math.min(matrix[i-1][j-1] + 1, // substitution
37517 Math.min(matrix[i][j-1] + 1, // insertion
37518 matrix[i-1][j] + 1)); // deletion
37522 return matrix[b.length][a.length];
37526 // a d3.mouse-alike which
37527 // 1. Only works on HTML elements, not SVG
37528 // 2. Does not cause style recalculation
37529 function utilFastMouse(container) {
37530 var rect = container.getBoundingClientRect(),
37531 rectLeft = rect.left,
37532 rectTop = rect.top,
37533 clientLeft = +container.clientLeft,
37534 clientTop = +container.clientTop;
37535 if (textDirection === 'rtl') {
37538 return function(e) {
37540 e.clientX - rectLeft - clientLeft,
37541 e.clientY - rectTop - clientTop];
37546 /* eslint-disable no-proto */
37547 var utilGetPrototypeOf = Object.getPrototypeOf || function(obj) { return obj.__proto__; };
37548 /* eslint-enable no-proto */
37551 function utilAsyncMap(inputs, func, callback) {
37552 var remaining = inputs.length,
37556 inputs.forEach(function(d, i) {
37557 func(d, function done(err, data) {
37561 if (!remaining) callback(errors, results);
37567 // wraps an index to an interval [0..length-1]
37568 function utilWrap(index, length) {
37570 index += Math.ceil(-index/length)*length;
37571 return index % length;
37576 * a replacement for functor
37578 * @param {*} value any value
37579 * @returns {Function} a function that returns that value or the value if it's a function
37581 function utilFunctor(value) {
37582 if (typeof value === 'function') return value;
37583 return function() {
37588 // A per-domain session mutex backed by a cookie and dead man's
37589 // switch. If the session crashes, the mutex will auto-release
37590 // after 5 seconds.
37592 function utilSessionMutex(name) {
37597 var expires = new Date();
37598 expires.setSeconds(expires.getSeconds() + 5);
37599 document.cookie = name + '=1; expires=' + expires.toUTCString();
37602 mutex.lock = function() {
37603 if (intervalID) return true;
37604 var cookie = document.cookie.replace(new RegExp('(?:(?:^|.*;)\\s*' + name + '\\s*\\=\\s*([^;]*).*$)|^.*$'), '$1');
37605 if (cookie) return false;
37607 intervalID = window.setInterval(renew, 4000);
37611 mutex.unlock = function() {
37612 if (!intervalID) return;
37613 document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
37614 clearInterval(intervalID);
37618 mutex.locked = function() {
37619 return !!intervalID;
37625 function utilSuggestNames(preset, suggestions) {
37626 preset = preset.id.split('/', 2);
37630 return function(value, callback) {
37632 if (value && value.length > 2) {
37633 if (suggestions[k] && suggestions[k][v]) {
37634 for (var sugg in suggestions[k][v]) {
37635 var dist = utilEditDistance(value, sugg.substring(0, value.length));
37645 result.sort(function(a, b) {
37646 return a.dist - b.dist;
37649 result = result.slice(0,3);
37654 function utilTriggerEvent(target, type) {
37655 target.each(function() {
37656 var evt = document.createEvent('HTMLEvents');
37657 evt.initEvent(type, true, true);
37658 this.dispatchEvent(evt);
37662 // Like selection.property('value', ...), but avoids no-op value sets,
37663 // which can result in layout/repaint thrashing in some situations.
37664 function utilGetSetValue(selection, value) {
37665 function d3_selection_value(value) {
37666 function valueNull() {
37670 function valueConstant() {
37671 if (this.value !== value) {
37672 this.value = value;
37676 function valueFunction() {
37677 var x = value.apply(this, arguments);
37680 } else if (this.value !== x) {
37685 return value == null
37686 ? valueNull : (typeof value === 'function'
37687 ? valueFunction : valueConstant);
37690 if (arguments.length === 1) {
37691 return selection.property('value');
37694 return selection.each(d3_selection_value(value));
37697 function validationDeprecatedTag() {
37699 var validation = function(changes) {
37701 for (var i = 0; i < changes.created.length; i++) {
37702 var change = changes.created[i],
37703 deprecatedTags = change.deprecatedTags();
37705 if (!lodash.isEmpty(deprecatedTags)) {
37706 var tags = utilTagText({ tags: deprecatedTags });
37708 id: 'deprecated_tags',
37709 message: t('validations.deprecated_tags', { tags: tags }),
37722 function validationManyDeletions() {
37723 var threshold = 100;
37725 var validation = function(changes) {
37727 if (changes.deleted.length > threshold) {
37729 id: 'many_deletions',
37730 message: t('validations.many_deletions', { n: changes.deleted.length })
37741 function validationMissingTag() {
37743 // Slightly stricter check than Entity#isUsed (#3091)
37744 function hasTags(entity, graph) {
37745 return lodash.without(Object.keys(entity.tags), 'area', 'name').length > 0 ||
37746 graph.parentRelations(entity).length > 0;
37749 var validation = function(changes, graph) {
37751 for (var i = 0; i < changes.created.length; i++) {
37752 var change = changes.created[i],
37753 geometry = change.geometry(graph);
37755 if ((geometry === 'point' || geometry === 'line' || geometry === 'area') && !hasTags(change, graph)) {
37758 message: t('validations.untagged_' + geometry),
37759 tooltip: t('validations.untagged_' + geometry + '_tooltip'),
37772 // https://github.com/openstreetmap/josm/blob/mirror/src/org/
37773 // openstreetmap/josm/data/validation/tests/UnclosedWays.java#L80
37774 function validationTagSuggestsArea() {
37776 function tagSuggestsArea(tags) {
37777 if (lodash.isEmpty(tags)) return false;
37779 var presence = ['landuse', 'amenities', 'tourism', 'shop'];
37780 for (var i = 0; i < presence.length; i++) {
37781 if (tags[presence[i]] !== undefined) {
37782 return presence[i] + '=' + tags[presence[i]];
37786 if (tags.building && tags.building === 'yes') return 'building=yes';
37790 var validation = function(changes, graph) {
37792 for (var i = 0; i < changes.created.length; i++) {
37793 var change = changes.created[i],
37794 geometry = change.geometry(graph),
37795 suggestion = (geometry === 'line' ? tagSuggestsArea(change.tags) : undefined);
37799 id: 'tag_suggests_area',
37800 message: t('validations.tag_suggests_area', { tag: suggestion }),
37815 var Validations = Object.freeze({
37816 validationDeprecatedTag: validationDeprecatedTag,
37817 validationManyDeletions: validationManyDeletions,
37818 validationMissingTag: validationMissingTag,
37819 validationTagSuggestsArea: validationTagSuggestsArea
37823 iD.Difference represents the difference between two graphs.
37824 It knows how to calculate the set of entities that were
37825 created, modified, or deleted, and also contains the logic
37826 for recursively extending a difference to the complete set
37827 of entities that will require a redraw, taking into account
37828 child and parent relationships.
37830 function coreDifference(base, head) {
37836 function changed(h, b) {
37837 return h !== b && !lodash.isEqual(lodash.omit(h, 'v'), lodash.omit(b, 'v'));
37841 lodash.each(head.entities, function(h, id) {
37842 var b = base.entities[id];
37843 if (changed(h, b)) {
37844 changes[id] = {base: b, head: h};
37850 lodash.each(base.entities, function(b, id) {
37851 var h = head.entities[id];
37852 if (!changes[id] && changed(h, b)) {
37853 changes[id] = {base: b, head: h};
37859 function addParents(parents, result) {
37860 for (var i = 0; i < parents.length; i++) {
37861 var parent = parents[i];
37863 if (parent.id in result)
37866 result[parent.id] = parent;
37867 addParents(head.parentRelations(parent), result);
37872 difference.length = function() {
37877 difference.changes = function() {
37882 difference.extantIDs = function() {
37884 lodash.each(changes, function(change, id) {
37885 if (change.head) result.push(id);
37891 difference.modified = function() {
37893 lodash.each(changes, function(change) {
37894 if (change.base && change.head) result.push(change.head);
37900 difference.created = function() {
37902 lodash.each(changes, function(change) {
37903 if (!change.base && change.head) result.push(change.head);
37909 difference.deleted = function() {
37911 lodash.each(changes, function(change) {
37912 if (change.base && !change.head) result.push(change.base);
37918 difference.summary = function() {
37921 function addEntity(entity, graph, changeType) {
37922 relevant[entity.id] = {
37925 changeType: changeType
37929 function addParents(entity) {
37930 var parents = head.parentWays(entity);
37931 for (var j = parents.length - 1; j >= 0; j--) {
37932 var parent = parents[j];
37933 if (!(parent.id in relevant)) addEntity(parent, head, 'modified');
37937 lodash.each(changes, function(change) {
37938 if (change.head && change.head.geometry(head) !== 'vertex') {
37939 addEntity(change.head, head, change.base ? 'modified' : 'created');
37941 } else if (change.base && change.base.geometry(base) !== 'vertex') {
37942 addEntity(change.base, base, 'deleted');
37944 } else if (change.base && change.head) { // modified vertex
37945 var moved = !lodash.isEqual(change.base.loc, change.head.loc),
37946 retagged = !lodash.isEqual(change.base.tags, change.head.tags);
37949 addParents(change.head);
37952 if (retagged || (moved && change.head.hasInterestingTags())) {
37953 addEntity(change.head, head, 'modified');
37956 } else if (change.head && change.head.hasInterestingTags()) { // created vertex
37957 addEntity(change.head, head, 'created');
37959 } else if (change.base && change.base.hasInterestingTags()) { // deleted vertex
37960 addEntity(change.base, base, 'deleted');
37964 return values(relevant);
37968 difference.complete = function(extent$$1) {
37969 var result = {}, id, change;
37971 for (id in changes) {
37972 change = changes[id];
37974 var h = change.head,
37979 (!h || !h.intersects(extent$$1, head)) &&
37980 (!b || !b.intersects(extent$$1, base)))
37985 if (entity.type === 'way') {
37986 var nh = h ? h.nodes : [],
37987 nb = b ? b.nodes : [],
37990 diff = lodash.difference(nh, nb);
37991 for (i = 0; i < diff.length; i++) {
37992 result[diff[i]] = head.hasEntity(diff[i]);
37995 diff = lodash.difference(nb, nh);
37996 for (i = 0; i < diff.length; i++) {
37997 result[diff[i]] = head.hasEntity(diff[i]);
38001 addParents(head.parentWays(entity), result);
38002 addParents(head.parentRelations(entity), result);
38012 function coreGraph$$1(other, mutable) {
38013 if (!(this instanceof coreGraph$$1)) return new coreGraph$$1(other, mutable);
38015 if (other instanceof coreGraph$$1) {
38016 var base = other.base();
38017 this.entities = lodash.assign(Object.create(base.entities), other.entities);
38018 this._parentWays = lodash.assign(Object.create(base.parentWays), other._parentWays);
38019 this._parentRels = lodash.assign(Object.create(base.parentRels), other._parentRels);
38022 this.entities = Object.create({});
38023 this._parentWays = Object.create({});
38024 this._parentRels = Object.create({});
38025 this.rebase(other || [], [this]);
38028 this.transients = {};
38029 this._childNodes = {};
38030 this.frozen = !mutable;
38034 coreGraph$$1.prototype = {
38036 hasEntity: function(id) {
38037 return this.entities[id];
38041 entity: function(id) {
38042 var entity = this.entities[id];
38044 throw new Error('entity ' + id + ' not found');
38050 transient: function(entity, key, fn) {
38051 var id = entity.id,
38052 transients = this.transients[id] ||
38053 (this.transients[id] = {});
38055 if (transients[key] !== undefined) {
38056 return transients[key];
38059 transients[key] = fn.call(entity);
38061 return transients[key];
38065 parentWays: function(entity) {
38066 var parents = this._parentWays[entity.id],
38070 for (var i = 0; i < parents.length; i++) {
38071 result.push(this.entity(parents[i]));
38078 isPoi: function(entity) {
38079 var parentWays = this._parentWays[entity.id];
38080 return !parentWays || parentWays.length === 0;
38084 isShared: function(entity) {
38085 var parentWays = this._parentWays[entity.id];
38086 return parentWays && parentWays.length > 1;
38090 parentRelations: function(entity) {
38091 var parents = this._parentRels[entity.id],
38095 for (var i = 0; i < parents.length; i++) {
38096 result.push(this.entity(parents[i]));
38103 childNodes: function(entity) {
38104 if (this._childNodes[entity.id]) return this._childNodes[entity.id];
38105 if (!entity.nodes) return [];
38108 for (var i = 0; i < entity.nodes.length; i++) {
38109 nodes[i] = this.entity(entity.nodes[i]);
38112 if (debug) Object.freeze(nodes);
38114 this._childNodes[entity.id] = nodes;
38115 return this._childNodes[entity.id];
38121 'entities': utilGetPrototypeOf(this.entities),
38122 'parentWays': utilGetPrototypeOf(this._parentWays),
38123 'parentRels': utilGetPrototypeOf(this._parentRels)
38128 // Unlike other graph methods, rebase mutates in place. This is because it
38129 // is used only during the history operation that merges newly downloaded
38130 // data into each state. To external consumers, it should appear as if the
38131 // graph always contained the newly downloaded data.
38132 rebase: function(entities, stack, force) {
38133 var base = this.base(),
38136 for (i = 0; i < entities.length; i++) {
38137 var entity = entities[i];
38139 if (!entity.visible || (!force && base.entities[entity.id]))
38142 // Merging data into the base graph
38143 base.entities[entity.id] = entity;
38144 this._updateCalculated(undefined, entity, base.parentWays, base.parentRels);
38146 // Restore provisionally-deleted nodes that are discovered to have an extant parent
38147 if (entity.type === 'way') {
38148 for (j = 0; j < entity.nodes.length; j++) {
38149 id = entity.nodes[j];
38150 for (k = 1; k < stack.length; k++) {
38151 var ents = stack[k].entities;
38152 if (ents.hasOwnProperty(id) && ents[id] === undefined) {
38160 for (i = 0; i < stack.length; i++) {
38161 stack[i]._updateRebased();
38166 _updateRebased: function() {
38167 var base = this.base(),
38168 i, k, child, id, keys;
38170 keys = Object.keys(this._parentWays);
38171 for (i = 0; i < keys.length; i++) {
38173 if (base.parentWays[child]) {
38174 for (k = 0; k < base.parentWays[child].length; k++) {
38175 id = base.parentWays[child][k];
38176 if (!this.entities.hasOwnProperty(id) && !lodash.includes(this._parentWays[child], id)) {
38177 this._parentWays[child].push(id);
38183 keys = Object.keys(this._parentRels);
38184 for (i = 0; i < keys.length; i++) {
38186 if (base.parentRels[child]) {
38187 for (k = 0; k < base.parentRels[child].length; k++) {
38188 id = base.parentRels[child][k];
38189 if (!this.entities.hasOwnProperty(id) && !lodash.includes(this._parentRels[child], id)) {
38190 this._parentRels[child].push(id);
38196 this.transients = {};
38198 // this._childNodes is not updated, under the assumption that
38199 // ways are always downloaded with their child nodes.
38203 // Updates calculated properties (parentWays, parentRels) for the specified change
38204 _updateCalculated: function(oldentity, entity, parentWays, parentRels) {
38206 parentWays = parentWays || this._parentWays;
38207 parentRels = parentRels || this._parentRels;
38209 var type = entity && entity.type || oldentity && oldentity.type,
38210 removed, added, ways, rels, i;
38213 if (type === 'way') {
38215 // Update parentWays
38216 if (oldentity && entity) {
38217 removed = lodash.difference(oldentity.nodes, entity.nodes);
38218 added = lodash.difference(entity.nodes, oldentity.nodes);
38219 } else if (oldentity) {
38220 removed = oldentity.nodes;
38222 } else if (entity) {
38224 added = entity.nodes;
38226 for (i = 0; i < removed.length; i++) {
38227 parentWays[removed[i]] = lodash.without(parentWays[removed[i]], oldentity.id);
38229 for (i = 0; i < added.length; i++) {
38230 ways = lodash.without(parentWays[added[i]], entity.id);
38231 ways.push(entity.id);
38232 parentWays[added[i]] = ways;
38235 } else if (type === 'relation') {
38237 // Update parentRels
38238 if (oldentity && entity) {
38239 removed = lodash.difference(oldentity.members, entity.members);
38240 added = lodash.difference(entity.members, oldentity);
38241 } else if (oldentity) {
38242 removed = oldentity.members;
38244 } else if (entity) {
38246 added = entity.members;
38248 for (i = 0; i < removed.length; i++) {
38249 parentRels[removed[i].id] = lodash.without(parentRels[removed[i].id], oldentity.id);
38251 for (i = 0; i < added.length; i++) {
38252 rels = lodash.without(parentRels[added[i].id], entity.id);
38253 rels.push(entity.id);
38254 parentRels[added[i].id] = rels;
38260 replace: function(entity) {
38261 if (this.entities[entity.id] === entity)
38264 return this.update(function() {
38265 this._updateCalculated(this.entities[entity.id], entity);
38266 this.entities[entity.id] = entity;
38271 remove: function(entity) {
38272 return this.update(function() {
38273 this._updateCalculated(entity, undefined);
38274 this.entities[entity.id] = undefined;
38279 revert: function(id) {
38280 var baseEntity = this.base().entities[id],
38281 headEntity = this.entities[id];
38283 if (headEntity === baseEntity)
38286 return this.update(function() {
38287 this._updateCalculated(headEntity, baseEntity);
38288 delete this.entities[id];
38293 update: function() {
38294 var graph = this.frozen ? coreGraph$$1(this, true) : this;
38296 for (var i = 0; i < arguments.length; i++) {
38297 arguments[i].call(graph, graph);
38300 if (this.frozen) graph.frozen = true;
38306 // Obliterates any existing entities
38307 load: function(entities) {
38308 var base = this.base();
38309 this.entities = Object.create(base.entities);
38311 for (var i in entities) {
38312 this.entities[i] = entities[i];
38313 this._updateCalculated(base.entities[i], this.entities[i]);
38320 var index$9 = partialSort;
38322 // Floyd-Rivest selection algorithm:
38323 // Rearrange items so that all items in the [left, k] range are smaller than all items in (k, right];
38324 // The k-th element will have the (k - left + 1)th smallest value in [left, right]
38326 function partialSort(arr, k, left, right, compare) {
38328 right = right || (arr.length - 1);
38329 compare = compare || defaultCompare;
38331 while (right > left) {
38332 if (right - left > 600) {
38333 var n = right - left + 1;
38334 var m = k - left + 1;
38335 var z = Math.log(n);
38336 var s = 0.5 * Math.exp(2 * z / 3);
38337 var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);
38338 var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));
38339 var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));
38340 partialSort(arr, k, newLeft, newRight, compare);
38347 swap(arr, left, k);
38348 if (compare(arr[right], t) > 0) swap(arr, left, right);
38354 while (compare(arr[i], t) < 0) i++;
38355 while (compare(arr[j], t) > 0) j--;
38358 if (compare(arr[left], t) === 0) swap(arr, left, j);
38361 swap(arr, j, right);
38364 if (j <= k) left = j + 1;
38365 if (k <= j) right = j - 1;
38369 function swap(arr, i, j) {
38375 function defaultCompare(a, b) {
38376 return a < b ? -1 : a > b ? 1 : 0;
38379 var index$8 = rbush;
38381 var quickselect = index$9;
38383 function rbush(maxEntries, format) {
38384 if (!(this instanceof rbush)) return new rbush(maxEntries, format);
38386 // max entries in a node is 9 by default; min node fill is 40% for best performance
38387 this._maxEntries = Math.max(4, maxEntries || 9);
38388 this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));
38391 this._initFormat(format);
38397 rbush.prototype = {
38400 return this._all(this.data, []);
38403 search: function (bbox) {
38405 var node = this.data,
38407 toBBox = this.toBBox;
38409 if (!intersects$1(bbox, node)) return result;
38411 var nodesToSearch = [],
38412 i, len, child, childBBox;
38415 for (i = 0, len = node.children.length; i < len; i++) {
38417 child = node.children[i];
38418 childBBox = node.leaf ? toBBox(child) : child;
38420 if (intersects$1(bbox, childBBox)) {
38421 if (node.leaf) result.push(child);
38422 else if (contains$1(bbox, childBBox)) this._all(child, result);
38423 else nodesToSearch.push(child);
38426 node = nodesToSearch.pop();
38432 collides: function (bbox) {
38434 var node = this.data,
38435 toBBox = this.toBBox;
38437 if (!intersects$1(bbox, node)) return false;
38439 var nodesToSearch = [],
38440 i, len, child, childBBox;
38443 for (i = 0, len = node.children.length; i < len; i++) {
38445 child = node.children[i];
38446 childBBox = node.leaf ? toBBox(child) : child;
38448 if (intersects$1(bbox, childBBox)) {
38449 if (node.leaf || contains$1(bbox, childBBox)) return true;
38450 nodesToSearch.push(child);
38453 node = nodesToSearch.pop();
38459 load: function (data) {
38460 if (!(data && data.length)) return this;
38462 if (data.length < this._minEntries) {
38463 for (var i = 0, len = data.length; i < len; i++) {
38464 this.insert(data[i]);
38469 // recursively build the tree with the given data from stratch using OMT algorithm
38470 var node = this._build(data.slice(), 0, data.length - 1, 0);
38472 if (!this.data.children.length) {
38473 // save as is if tree is empty
38476 } else if (this.data.height === node.height) {
38477 // split root if trees have the same height
38478 this._splitRoot(this.data, node);
38481 if (this.data.height < node.height) {
38482 // swap trees if inserted one is bigger
38483 var tmpNode = this.data;
38488 // insert the small tree into the large tree at appropriate level
38489 this._insert(node, this.data.height - node.height - 1, true);
38495 insert: function (item) {
38496 if (item) this._insert(item, this.data.height - 1);
38500 clear: function () {
38501 this.data = createNode([]);
38505 remove: function (item, equalsFn) {
38506 if (!item) return this;
38508 var node = this.data,
38509 bbox = this.toBBox(item),
38512 i, parent, index, goingUp;
38514 // depth-first iterative tree traversal
38515 while (node || path.length) {
38517 if (!node) { // go up
38519 parent = path[path.length - 1];
38524 if (node.leaf) { // check current node
38525 index = findItem(item, node.children, equalsFn);
38527 if (index !== -1) {
38528 // item found, remove the item and condense tree upwards
38529 node.children.splice(index, 1);
38531 this._condense(path);
38536 if (!goingUp && !node.leaf && contains$1(node, bbox)) { // go down
38541 node = node.children[0];
38543 } else if (parent) { // go right
38545 node = parent.children[i];
38548 } else node = null; // nothing found
38554 toBBox: function (item) { return item; },
38556 compareMinX: compareNodeMinX,
38557 compareMinY: compareNodeMinY,
38559 toJSON: function () { return this.data; },
38561 fromJSON: function (data) {
38566 _all: function (node, result) {
38567 var nodesToSearch = [];
38569 if (node.leaf) result.push.apply(result, node.children);
38570 else nodesToSearch.push.apply(nodesToSearch, node.children);
38572 node = nodesToSearch.pop();
38577 _build: function (items, left, right, height) {
38579 var N = right - left + 1,
38580 M = this._maxEntries,
38584 // reached leaf level; return leaf
38585 node = createNode(items.slice(left, right + 1));
38586 calcBBox(node, this.toBBox);
38591 // target height of the bulk-loaded tree
38592 height = Math.ceil(Math.log(N) / Math.log(M));
38594 // target number of root entries to maximize storage utilization
38595 M = Math.ceil(N / Math.pow(M, height - 1));
38598 node = createNode([]);
38600 node.height = height;
38602 // split the items into M mostly square tiles
38604 var N2 = Math.ceil(N / M),
38605 N1 = N2 * Math.ceil(Math.sqrt(M)),
38606 i, j, right2, right3;
38608 multiSelect(items, left, right, N1, this.compareMinX);
38610 for (i = left; i <= right; i += N1) {
38612 right2 = Math.min(i + N1 - 1, right);
38614 multiSelect(items, i, right2, N2, this.compareMinY);
38616 for (j = i; j <= right2; j += N2) {
38618 right3 = Math.min(j + N2 - 1, right2);
38620 // pack each entry recursively
38621 node.children.push(this._build(items, j, right3, height - 1));
38625 calcBBox(node, this.toBBox);
38630 _chooseSubtree: function (bbox, node, level, path) {
38632 var i, len, child, targetNode, area, enlargement, minArea, minEnlargement;
38637 if (node.leaf || path.length - 1 === level) break;
38639 minArea = minEnlargement = Infinity;
38641 for (i = 0, len = node.children.length; i < len; i++) {
38642 child = node.children[i];
38643 area = bboxArea(child);
38644 enlargement = enlargedArea(bbox, child) - area;
38646 // choose entry with the least area enlargement
38647 if (enlargement < minEnlargement) {
38648 minEnlargement = enlargement;
38649 minArea = area < minArea ? area : minArea;
38650 targetNode = child;
38652 } else if (enlargement === minEnlargement) {
38653 // otherwise choose one with the smallest area
38654 if (area < minArea) {
38656 targetNode = child;
38661 node = targetNode || node.children[0];
38667 _insert: function (item, level, isNode) {
38669 var toBBox = this.toBBox,
38670 bbox = isNode ? item : toBBox(item),
38673 // find the best node for accommodating the item, saving all nodes along the path too
38674 var node = this._chooseSubtree(bbox, this.data, level, insertPath);
38676 // put the item into the node
38677 node.children.push(item);
38678 extend$1(node, bbox);
38680 // split on node overflow; propagate upwards if necessary
38681 while (level >= 0) {
38682 if (insertPath[level].children.length > this._maxEntries) {
38683 this._split(insertPath, level);
38688 // adjust bboxes along the insertion path
38689 this._adjustParentBBoxes(bbox, insertPath, level);
38692 // split overflowed node into two
38693 _split: function (insertPath, level) {
38695 var node = insertPath[level],
38696 M = node.children.length,
38697 m = this._minEntries;
38699 this._chooseSplitAxis(node, m, M);
38701 var splitIndex = this._chooseSplitIndex(node, m, M);
38703 var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));
38704 newNode.height = node.height;
38705 newNode.leaf = node.leaf;
38707 calcBBox(node, this.toBBox);
38708 calcBBox(newNode, this.toBBox);
38710 if (level) insertPath[level - 1].children.push(newNode);
38711 else this._splitRoot(node, newNode);
38714 _splitRoot: function (node, newNode) {
38716 this.data = createNode([node, newNode]);
38717 this.data.height = node.height + 1;
38718 this.data.leaf = false;
38719 calcBBox(this.data, this.toBBox);
38722 _chooseSplitIndex: function (node, m, M) {
38724 var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index;
38726 minOverlap = minArea = Infinity;
38728 for (i = m; i <= M - m; i++) {
38729 bbox1 = distBBox(node, 0, i, this.toBBox);
38730 bbox2 = distBBox(node, i, M, this.toBBox);
38732 overlap = intersectionArea(bbox1, bbox2);
38733 area = bboxArea(bbox1) + bboxArea(bbox2);
38735 // choose distribution with minimum overlap
38736 if (overlap < minOverlap) {
38737 minOverlap = overlap;
38740 minArea = area < minArea ? area : minArea;
38742 } else if (overlap === minOverlap) {
38743 // otherwise choose distribution with minimum area
38744 if (area < minArea) {
38754 // sorts node children by the best axis for split
38755 _chooseSplitAxis: function (node, m, M) {
38757 var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX,
38758 compareMinY = node.leaf ? this.compareMinY : compareNodeMinY,
38759 xMargin = this._allDistMargin(node, m, M, compareMinX),
38760 yMargin = this._allDistMargin(node, m, M, compareMinY);
38762 // if total distributions margin value is minimal for x, sort by minX,
38763 // otherwise it's already sorted by minY
38764 if (xMargin < yMargin) node.children.sort(compareMinX);
38767 // total margin of all possible split distributions where each node is at least m full
38768 _allDistMargin: function (node, m, M, compare) {
38770 node.children.sort(compare);
38772 var toBBox = this.toBBox,
38773 leftBBox = distBBox(node, 0, m, toBBox),
38774 rightBBox = distBBox(node, M - m, M, toBBox),
38775 margin = bboxMargin(leftBBox) + bboxMargin(rightBBox),
38778 for (i = m; i < M - m; i++) {
38779 child = node.children[i];
38780 extend$1(leftBBox, node.leaf ? toBBox(child) : child);
38781 margin += bboxMargin(leftBBox);
38784 for (i = M - m - 1; i >= m; i--) {
38785 child = node.children[i];
38786 extend$1(rightBBox, node.leaf ? toBBox(child) : child);
38787 margin += bboxMargin(rightBBox);
38793 _adjustParentBBoxes: function (bbox, path, level) {
38794 // adjust bboxes along the given tree path
38795 for (var i = level; i >= 0; i--) {
38796 extend$1(path[i], bbox);
38800 _condense: function (path) {
38801 // go through the path, removing empty nodes and updating bboxes
38802 for (var i = path.length - 1, siblings; i >= 0; i--) {
38803 if (path[i].children.length === 0) {
38805 siblings = path[i - 1].children;
38806 siblings.splice(siblings.indexOf(path[i]), 1);
38808 } else this.clear();
38810 } else calcBBox(path[i], this.toBBox);
38814 _initFormat: function (format) {
38815 // data format (minX, minY, maxX, maxY accessors)
38817 // uses eval-type function compilation instead of just accepting a toBBox function
38818 // because the algorithms are very sensitive to sorting functions performance,
38819 // so they should be dead simple and without inner calls
38821 var compareArr = ['return a', ' - b', ';'];
38823 this.compareMinX = new Function('a', 'b', compareArr.join(format[0]));
38824 this.compareMinY = new Function('a', 'b', compareArr.join(format[1]));
38826 this.toBBox = new Function('a',
38827 'return {minX: a' + format[0] +
38828 ', minY: a' + format[1] +
38829 ', maxX: a' + format[2] +
38830 ', maxY: a' + format[3] + '};');
38834 function findItem(item, items, equalsFn) {
38835 if (!equalsFn) return items.indexOf(item);
38837 for (var i = 0; i < items.length; i++) {
38838 if (equalsFn(item, items[i])) return i;
38843 // calculate node's bbox from bboxes of its children
38844 function calcBBox(node, toBBox) {
38845 distBBox(node, 0, node.children.length, toBBox, node);
38848 // min bounding rectangle of node children from k to p-1
38849 function distBBox(node, k, p, toBBox, destNode) {
38850 if (!destNode) destNode = createNode(null);
38851 destNode.minX = Infinity;
38852 destNode.minY = Infinity;
38853 destNode.maxX = -Infinity;
38854 destNode.maxY = -Infinity;
38856 for (var i = k, child; i < p; i++) {
38857 child = node.children[i];
38858 extend$1(destNode, node.leaf ? toBBox(child) : child);
38864 function extend$1(a, b) {
38865 a.minX = Math.min(a.minX, b.minX);
38866 a.minY = Math.min(a.minY, b.minY);
38867 a.maxX = Math.max(a.maxX, b.maxX);
38868 a.maxY = Math.max(a.maxY, b.maxY);
38872 function compareNodeMinX(a, b) { return a.minX - b.minX; }
38873 function compareNodeMinY(a, b) { return a.minY - b.minY; }
38875 function bboxArea(a) { return (a.maxX - a.minX) * (a.maxY - a.minY); }
38876 function bboxMargin(a) { return (a.maxX - a.minX) + (a.maxY - a.minY); }
38878 function enlargedArea(a, b) {
38879 return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *
38880 (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY));
38883 function intersectionArea(a, b) {
38884 var minX = Math.max(a.minX, b.minX),
38885 minY = Math.max(a.minY, b.minY),
38886 maxX = Math.min(a.maxX, b.maxX),
38887 maxY = Math.min(a.maxY, b.maxY);
38889 return Math.max(0, maxX - minX) *
38890 Math.max(0, maxY - minY);
38893 function contains$1(a, b) {
38894 return a.minX <= b.minX &&
38895 a.minY <= b.minY &&
38896 b.maxX <= a.maxX &&
38900 function intersects$1(a, b) {
38901 return b.minX <= a.maxX &&
38902 b.minY <= a.maxY &&
38903 b.maxX >= a.minX &&
38907 function createNode(children) {
38909 children: children,
38919 // sort an array so that items come in groups of n unsorted items, with groups sorted between each other;
38920 // combines selection algorithm with binary divide & conquer approach
38922 function multiSelect(arr, left, right, n, compare) {
38923 var stack = [left, right],
38926 while (stack.length) {
38927 right = stack.pop();
38928 left = stack.pop();
38930 if (right - left <= n) continue;
38932 mid = left + Math.ceil((right - left) / n / 2) * n;
38933 quickselect(arr, mid, left, right, compare);
38935 stack.push(left, mid, mid, right);
38939 function coreTree(head) {
38940 var rtree = index$8(),
38945 function entityBBox(entity) {
38946 var bbox = entity.extent(head).bbox();
38947 bbox.id = entity.id;
38948 bboxes[entity.id] = bbox;
38953 function updateParents(entity, insertions, memo) {
38954 head.parentWays(entity).forEach(function(way) {
38955 if (bboxes[way.id]) {
38956 rtree.remove(bboxes[way.id]);
38957 insertions[way.id] = way;
38959 updateParents(way, insertions, memo);
38962 head.parentRelations(entity).forEach(function(relation) {
38963 if (memo[entity.id]) return;
38964 memo[entity.id] = true;
38965 if (bboxes[relation.id]) {
38966 rtree.remove(bboxes[relation.id]);
38967 insertions[relation.id] = relation;
38969 updateParents(relation, insertions, memo);
38974 tree.rebase = function(entities, force) {
38975 var insertions = {};
38977 for (var i = 0; i < entities.length; i++) {
38978 var entity = entities[i];
38980 if (!entity.visible)
38983 if (head.entities.hasOwnProperty(entity.id) || bboxes[entity.id]) {
38986 } else if (bboxes[entity.id]) {
38987 rtree.remove(bboxes[entity.id]);
38991 insertions[entity.id] = entity;
38992 updateParents(entity, insertions, {});
38995 rtree.load(lodash.map(insertions, entityBBox));
39001 tree.intersects = function(extent, graph) {
39002 if (graph !== head) {
39003 var diff = coreDifference(head, graph),
39008 diff.deleted().forEach(function(entity) {
39009 rtree.remove(bboxes[entity.id]);
39010 delete bboxes[entity.id];
39013 diff.modified().forEach(function(entity) {
39014 rtree.remove(bboxes[entity.id]);
39015 insertions[entity.id] = entity;
39016 updateParents(entity, insertions, {});
39019 diff.created().forEach(function(entity) {
39020 insertions[entity.id] = entity;
39023 rtree.load(lodash.map(insertions, entityBBox));
39026 return rtree.search(extent.bbox()).map(function(bbox) {
39027 return head.entity(bbox.id);
39036 * This code is licensed under the MIT license.
39038 * Copyright © 2013, iD authors.
39040 * Portions copyright © 2011, Keith Cirkel
39041 * See https://github.com/keithamus/jwerty
39044 function d3keybinding(namespace$$1) {
39047 function matches(binding, event$$1) {
39048 for (var p in binding.event) {
39049 if (event$$1[p] !== binding.event[p])
39055 function testBindings(isCapturing) {
39056 for (var i = 0; i < bindings.length; i++) {
39057 var binding = bindings[i];
39059 if (!!binding.capture === isCapturing && matches(binding, event)) {
39060 binding.callback();
39065 function capture() {
39066 testBindings(true);
39069 function bubble() {
39070 var tagName = select(event.target).node().tagName;
39071 if (tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA') {
39074 testBindings(false);
39077 function keybinding(selection$$1) {
39078 selection$$1 = selection$$1 || select(document);
39079 selection$$1.on('keydown.capture' + namespace$$1, capture, true);
39080 selection$$1.on('keydown.bubble' + namespace$$1, bubble, false);
39084 keybinding.off = function(selection$$1) {
39086 selection$$1 = selection$$1 || select(document);
39087 selection$$1.on('keydown.capture' + namespace$$1, null);
39088 selection$$1.on('keydown.bubble' + namespace$$1, null);
39092 keybinding.on = function(codes, callback, capture) {
39093 var arr = [].concat(codes);
39094 for (var i = 0; i < arr.length; i++) {
39108 code = code.toLowerCase().match(/(?:(?:[^+⇧⌃⌥⌘])+|[⇧⌃⌥⌘]|\+\+|^\+$)/g);
39110 for (var j = 0; j < code.length; j++) {
39111 // Normalise matching errors
39112 if (code[j] === '++') code[i] = '+';
39114 if (code[j] in d3keybinding.modifierCodes) {
39115 binding.event[d3keybinding.modifierProperties[d3keybinding.modifierCodes[code[j]]]] = true;
39116 } else if (code[j] in d3keybinding.keyCodes) {
39117 binding.event.keyCode = d3keybinding.keyCodes[code[j]];
39121 bindings.push(binding);
39131 d3keybinding.modifierCodes = {
39133 '⇧': 16, shift: 16,
39134 // CTRL key, on Mac: ⌃
39136 // ALT key, on Mac: ⌥ (Alt)
39137 '⌥': 18, alt: 18, option: 18,
39138 // META, on Mac: ⌘ (CMD), on Windows (Win), on Linux (Super)
39139 '⌘': 91, meta: 91, cmd: 91, 'super': 91, win: 91
39142 d3keybinding.modifierProperties = {
39149 d3keybinding.keyCodes = {
39150 // Backspace key, on Mac: ⌫ (Backspace)
39151 '⌫': 8, backspace: 8,
39152 // Tab Key, on Mac: ⇥ (Tab), on Windows ⇥⇥
39153 '⇥': 9, '⇆': 9, tab: 9,
39155 '↩': 13, 'return': 13, enter: 13, '⌅': 13,
39157 'pause': 19, 'pause-break': 19,
39158 // Caps Lock key, ⇪
39159 '⇪': 20, caps: 20, 'caps-lock': 20,
39160 // Escape key, on Mac: ⎋, on Windows: Esc
39161 '⎋': 27, escape: 27, esc: 27,
39164 // Page-Up key, or pgup, on Mac: ↖
39165 '↖': 33, pgup: 33, 'page-up': 33,
39166 // Page-Down key, or pgdown, on Mac: ↘
39167 '↘': 34, pgdown: 34, 'page-down': 34,
39168 // END key, on Mac: ⇟
39170 // HOME key, on Mac: ⇞
39172 // Insert key, or ins
39173 ins: 45, insert: 45,
39174 // Delete key, on Mac: ⌦ (Delete)
39175 '⌦': 46, del: 46, 'delete': 46,
39176 // Left Arrow Key, or ←
39177 '←': 37, left: 37, 'arrow-left': 37,
39178 // Up Arrow Key, or ↑
39179 '↑': 38, up: 38, 'arrow-up': 38,
39180 // Right Arrow Key, or →
39181 '→': 39, right: 39, 'arrow-right': 39,
39182 // Up Arrow Key, or ↓
39183 '↓': 40, down: 40, 'arrow-down': 40,
39184 // odities, printing characters that come out wrong:
39187 // Num-Multiply, or *
39188 '*': 106, star: 106, asterisk: 106, multiply: 106,
39190 '+': 107, 'plus': 107,
39191 // Num-Subtract, or -
39192 '-': 109, subtract: 109,
39198 ';': 186, semicolon: 186,
39200 '=': 187, 'equals': 187,
39202 ',': 188, comma: 188,
39203 // Dash / Underscore key
39205 // Period, or ., or full-stop
39206 '.': 190, period: 190, 'full-stop': 190,
39207 // Slash, or /, or forward-slash
39208 '/': 191, slash: 191, 'forward-slash': 191,
39209 // Tick, or `, or back-quote
39210 '`': 192, tick: 192, 'back-quote': 192,
39211 // Open bracket, or [
39212 '[': 219, 'open-bracket': 219,
39213 // Back slash, or \
39214 '\\': 220, 'back-slash': 220,
39215 // Close backet, or ]
39216 ']': 221, 'close-bracket': 221,
39217 // Apostrophe, or Quote, or '
39218 '\'': 222, quote: 222, apostrophe: 222
39224 while (++i$1 < 106) {
39225 d3keybinding.keyCodes['num-' + n] = i$1;
39231 while (++i$1 < 58) {
39232 d3keybinding.keyCodes[n] = i$1;
39238 while (++i$1 < 136) {
39239 d3keybinding.keyCodes['f' + n] = i$1;
39245 while (++i$1 < 91) {
39246 d3keybinding.keyCodes[String.fromCharCode(i$1).toLowerCase()] = i$1;
39249 function tooltip() {
39250 var tooltip = function(selection$$1) {
39251 selection$$1.each(setup);
39253 animation = utilFunctor(false),
39254 html$$1 = utilFunctor(false),
39255 title = function() {
39256 var title = this.getAttribute('data-original-title');
39260 title = this.getAttribute('title');
39261 this.removeAttribute('title');
39262 this.setAttribute('data-original-title', title);
39266 over = 'mouseenter.tooltip',
39267 out = 'mouseleave.tooltip',
39268 placement = utilFunctor('top');
39271 tooltip.title = function(_) {
39272 if (arguments.length) {
39273 title = utilFunctor(_);
39281 tooltip.html = function(_) {
39282 if (arguments.length) {
39283 html$$1 = utilFunctor(_);
39291 tooltip.placement = function(_) {
39292 if (arguments.length) {
39293 placement = utilFunctor(_);
39301 tooltip.show = function(selection$$1) {
39302 selection$$1.each(show);
39306 tooltip.hide = function(selection$$1) {
39307 selection$$1.each(hide);
39311 tooltip.toggle = function(selection$$1) {
39312 selection$$1.each(toggle);
39316 tooltip.destroy = function(selection$$1) {
39320 .attr('title', function() {
39321 return this.getAttribute('data-original-title') || this.getAttribute('title');
39323 .attr('data-original-title', null)
39324 .selectAll('.tooltip')
39330 var root = select(this),
39331 animate = animation.apply(this, arguments),
39332 tip = root.selectAll('.tooltip').data([0]);
39334 var enter = tip.enter()
39336 .attr('class', 'tooltip');
39340 .attr('class', 'tooltip-arrow');
39344 .attr('class', 'tooltip-inner');
39350 tip.classed('fade', true);
39353 var place = placement.apply(this, arguments);
39354 tip.classed(place, true);
39356 root.on(over, show);
39357 root.on(out, hide);
39362 var root = select(this),
39363 content = title.apply(this, arguments),
39364 tip = root.selectAll('.tooltip')
39365 .classed('in', true),
39366 markup = html$$1.apply(this, arguments);
39368 tip.selectAll('.tooltip-inner')[markup ? 'html' : 'text'](content);
39369 var place = placement.apply(this, arguments),
39370 outer = getPosition(root.node()),
39371 inner = getPosition(tip.node()),
39376 pos = {x: outer.x + (outer.w - inner.w) / 2, y: outer.y - inner.h};
39379 pos = {x: outer.x + outer.w, y: outer.y + (outer.h - inner.h) / 2};
39382 pos = {x: outer.x - inner.w, y: outer.y + (outer.h - inner.h) / 2};
39385 pos = {x: Math.max(0, outer.x + (outer.w - inner.w) / 2), y: outer.y + outer.h};
39390 tip.style('left', ~~pos.x + 'px').style('top', ~~pos.y + 'px');
39392 tip.style('left', null).style('top', null);
39395 this.tooltipVisible = true;
39400 select(this).selectAll('.tooltip')
39401 .classed('in', false);
39403 this.tooltipVisible = false;
39407 function toggle() {
39408 if (this.tooltipVisible) {
39409 hide.apply(this, arguments);
39411 show.apply(this, arguments);
39419 function getPosition(node) {
39420 var mode = select(node).style('position');
39421 if (mode === 'absolute' || mode === 'static') {
39423 x: node.offsetLeft,
39425 w: node.offsetWidth,
39426 h: node.offsetHeight
39432 w: node.offsetWidth,
39433 h: node.offsetHeight
39438 function svgAreas$$1(projection, context) {
39439 // Patterns only work in Firefox when set directly on element.
39440 // (This is not a bug: https://bugzilla.mozilla.org/show_bug.cgi?id=750632)
39442 wetland: 'wetland',
39445 construction: 'construction',
39446 military: 'construction',
39447 cemetery: 'cemetery',
39448 grave_yard: 'cemetery',
39451 farmland: 'farmland',
39455 var patternKeys = ['landuse', 'natural', 'amenity'];
39458 function setPattern(d) {
39459 for (var i = 0; i < patternKeys.length; i++) {
39460 if (patterns.hasOwnProperty(d.tags[patternKeys[i]])) {
39461 this.style.fill = this.style.stroke = 'url("#pattern-' + patterns[d.tags[patternKeys[i]]] + '")';
39465 this.style.fill = this.style.stroke = '';
39469 return function drawAreas(selection$$1, graph, entities, filter) {
39470 var path$$1 = svgPath(projection, graph, true),
39474 for (var i = 0; i < entities.length; i++) {
39475 var entity = entities[i];
39476 if (entity.geometry(graph) !== 'area') continue;
39478 multipolygon = osmIsSimpleMultipolygonOuterMember(entity, graph);
39479 if (multipolygon) {
39480 areas[multipolygon.id] = {
39481 entity: multipolygon.mergeTags(entity.tags),
39482 area: Math.abs(entity.area(graph))
39484 } else if (!areas[entity.id]) {
39485 areas[entity.id] = {
39487 area: Math.abs(entity.area(graph))
39492 areas = values(areas).filter(function hasPath(a) { return path$$1(a.entity); });
39493 areas.sort(function areaSort(a, b) { return b.area - a.area; });
39494 areas = lodash.map(areas, 'entity');
39496 var strokes = areas.filter(function(area$$1) {
39497 return area$$1.type === 'way';
39507 var clipPaths = context.surface().selectAll('defs').selectAll('.clipPath')
39509 .data(data.clip, osmEntity$$1.key);
39514 var clipPathsEnter = clipPaths.enter()
39515 .append('clipPath')
39516 .attr('class', 'clipPath')
39517 .attr('id', function(entity) { return entity.id + '-clippath'; });
39522 clipPaths.merge(clipPathsEnter)
39524 .attr('d', path$$1);
39527 var layer = selection$$1.selectAll('.layer-areas');
39529 var areagroup = layer
39530 .selectAll('g.areagroup')
39531 .data(['fill', 'shadow', 'stroke']);
39533 areagroup = areagroup.enter()
39535 .attr('class', function(d) { return 'areagroup area-' + d; })
39538 var paths = areagroup
39541 .data(function(layer) { return data[layer]; }, osmEntity$$1.key);
39546 var fills = selection$$1.selectAll('.area-fill path.area').nodes();
39548 var bisect$$1 = bisector(function(node) {
39549 return -node.__data__.area(graph);
39552 function sortedByArea(entity) {
39553 if (this._parent.__data__ === 'fill') {
39554 return fills[bisect$$1(fills, -entity.area(graph))];
39558 paths = paths.enter()
39559 .insert('path', sortedByArea)
39561 .each(function(entity) {
39562 var layer = this.parentNode.__data__;
39564 this.setAttribute('class', entity.type + ' area ' + layer + ' ' + entity.id);
39566 if (layer === 'fill') {
39567 this.setAttribute('clip-path', 'url(#' + entity.id + '-clippath)');
39568 setPattern.apply(this, arguments);
39571 .call(svgTagClasses())
39572 .attr('d', path$$1);
39576 function svgDebug(projection, context) {
39578 function multipolygons(imagery) {
39579 return imagery.map(function(data$$1) {
39581 type: 'MultiPolygon',
39582 coordinates: [ data$$1.polygon ]
39587 function drawDebug(selection$$1) {
39588 var showsTile = context.getDebug('tile'),
39589 showsCollision = context.getDebug('collision'),
39590 showsImagery = context.getDebug('imagery'),
39591 showsImperial = context.getDebug('imperial'),
39592 showsDriveLeft = context.getDebug('driveLeft'),
39593 path$$1 = index$5(projection);
39596 var debugData = [];
39598 debugData.push({ class: 'red', label: 'tile' });
39600 if (showsCollision) {
39601 debugData.push({ class: 'yellow', label: 'collision' });
39603 if (showsImagery) {
39604 debugData.push({ class: 'orange', label: 'imagery' });
39606 if (showsImperial) {
39607 debugData.push({ class: 'cyan', label: 'imperial' });
39609 if (showsDriveLeft) {
39610 debugData.push({ class: 'green', label: 'driveLeft' });
39614 var legend = select('#content')
39615 .selectAll('.debug-legend')
39616 .data(debugData.length ? [0] : []);
39621 legend = legend.enter()
39623 .attr('class', 'fillD debug-legend')
39627 var legendItems = legend.selectAll('.debug-legend-item')
39628 .data(debugData, function(d) { return d.label; });
39633 legendItems.enter()
39635 .attr('class', function(d) { return 'debug-legend-item ' + d.class; })
39636 .text(function(d) { return d.label; });
39639 var layer = selection$$1.selectAll('.layer-debug')
39640 .data(showsImagery || showsImperial || showsDriveLeft ? [0] : []);
39645 layer = layer.enter()
39647 .attr('class', 'layer-debug')
39651 var extent$$1 = context.map().extent(),
39652 dataImagery = data.imagery || [],
39653 availableImagery = showsImagery && multipolygons(dataImagery.filter(function(source) {
39654 if (!source.polygon) return false;
39655 return source.polygon.some(function(polygon) {
39656 return geoPolygonIntersectsPolygon(polygon, extent$$1, true);
39660 var imagery = layer.selectAll('path.debug-imagery')
39661 .data(showsImagery ? availableImagery : []);
39668 .attr('class', 'debug-imagery debug orange');
39671 var imperial = layer
39672 .selectAll('path.debug-imperial')
39673 .data(showsImperial ? [dataImperial] : []);
39680 .attr('class', 'debug-imperial debug cyan');
39683 var driveLeft = layer
39684 .selectAll('path.debug-drive-left')
39685 .data(showsDriveLeft ? [dataDriveLeft] : []);
39692 .attr('class', 'debug-drive-left debug green');
39696 layer.selectAll('path')
39697 .attr('d', path$$1);
39701 // This looks strange because `enabled` methods on other layers are
39702 // chainable getter/setters, and this one is just a getter.
39703 drawDebug.enabled = function() {
39704 if (!arguments.length) {
39705 return context.getDebug('tile') ||
39706 context.getDebug('collision') ||
39707 context.getDebug('imagery') ||
39708 context.getDebug('imperial') ||
39709 context.getDebug('driveLeft');
39720 A standalone SVG element that contains only a `defs` sub-element. To be
39721 used once globally, since defs IDs must be unique within a document.
39723 function svgDefs(context) {
39725 function SVGSpriteDefinition(id, href) {
39726 return function(defs) {
39728 .mimeType('image/svg+xml')
39729 .response(function(xhr) { return xhr.responseXML; })
39730 .get(function(err, svg) {
39732 defs.node().appendChild(
39733 select(svg.documentElement).attr('id', id).node()
39740 return function drawDefs(selection$$1) {
39741 var defs = selection$$1.append('defs');
39744 defs.append('marker')
39745 .attr('id', 'oneway-marker')
39746 .attr('viewBox', '0 0 10 10')
39749 .attr('markerWidth', 2)
39750 .attr('markerHeight', 2)
39751 .attr('markerUnits', 'strokeWidth')
39752 .attr('orient', 'auto')
39755 .attr('class', 'oneway')
39756 .attr('d', 'M 5 3 L 0 3 L 0 2 L 5 2 L 5 0 L 10 2.5 L 5 5 z')
39757 .attr('stroke', 'none')
39758 .attr('fill', '#000')
39759 .attr('opacity', '0.5');
39762 var patterns = defs.selectAll('pattern')
39764 // pattern name, pattern image name
39765 ['wetland', 'wetland'],
39766 ['construction', 'construction'],
39767 ['cemetery', 'cemetery'],
39768 ['orchard', 'orchard'],
39769 ['farmland', 'farmland'],
39776 .attr('id', function (d) {
39777 return 'pattern-' + d[0];
39780 .attr('height', 32)
39781 .attr('patternUnits', 'userSpaceOnUse');
39783 patterns.append('rect')
39787 .attr('height', 32)
39788 .attr('class', function (d) {
39789 return 'pattern-color-' + d[0];
39792 patterns.append('image')
39796 .attr('height', 32)
39797 .attr('xlink:href', function (d) {
39798 return context.imagePath('pattern/' + d[1] + '.png');
39803 .data([12, 18, 20, 32, 45])
39805 .append('clipPath')
39806 .attr('id', function (d) {
39807 return 'clip-square-' + d;
39812 .attr('width', function (d) {
39815 .attr('height', function (d) {
39819 defs.call(SVGSpriteDefinition(
39821 context.imagePath('iD-sprite.svg')));
39823 defs.call(SVGSpriteDefinition(
39825 context.imagePath('maki-sprite.svg')));
39829 var sax = createCommonjsModule(function (module, exports) {
39830 //[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
39831 //[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
39832 //[5] Name ::= NameStartChar (NameChar)*
39833 var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/;//\u10000-\uEFFFF
39834 var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\u00B7\u0300-\u036F\\u203F-\u2040]");
39835 var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$');
39836 //var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
39837 //var handlers = 'resolveEntity,getExternalSubset,characters,endDocument,endElement,endPrefixMapping,ignorableWhitespace,processingInstruction,setDocumentLocator,skippedEntity,startDocument,startElement,startPrefixMapping,notationDecl,unparsedEntityDecl,error,fatalError,warning,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,comment,endCDATA,endDTD,endEntity,startCDATA,startDTD,startEntity'.split(',')
39839 //S_TAG, S_ATTR, S_EQ, S_V
39840 //S_ATTR_S, S_E, S_S, S_C
39841 var S_TAG = 0;//tag name offerring
39842 var S_ATTR = 1;//attr name offerring
39843 var S_ATTR_S=2;//attr name end and space offer
39844 var S_EQ = 3;//=space?
39845 var S_V = 4;//attr value(no quot value only)
39846 var S_E = 5;//attr value end and no space(quot end)
39847 var S_S = 6;//(attr value end || tag end ) && (space offer)
39848 var S_C = 7;//closed el<el />
39850 function XMLReader(){
39854 XMLReader.prototype = {
39855 parse:function(source,defaultNSMap,entityMap){
39856 var domBuilder = this.domBuilder;
39857 domBuilder.startDocument();
39858 _copy(defaultNSMap ,defaultNSMap = {});
39859 parse(source,defaultNSMap,entityMap,
39860 domBuilder,this.errorHandler);
39861 domBuilder.endDocument();
39864 function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){
39865 function fixedFromCharCode(code) {
39866 // String.prototype.fromCharCode does not supports
39867 // > 2 bytes unicode chars directly
39868 if (code > 0xffff) {
39870 var surrogate1 = 0xd800 + (code >> 10)
39871 , surrogate2 = 0xdc00 + (code & 0x3ff);
39873 return String.fromCharCode(surrogate1, surrogate2);
39875 return String.fromCharCode(code);
39878 function entityReplacer(a){
39879 var k = a.slice(1,-1);
39880 if(k in entityMap){
39881 return entityMap[k];
39882 }else if(k.charAt(0) === '#'){
39883 return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x')))
39885 errorHandler.error('entity not found:'+a);
39889 function appendText(end){//has some bugs
39891 var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer);
39892 locator&&position(start);
39893 domBuilder.characters(xt,0,end-start);
39897 function position(p,m){
39898 while(p>=lineEnd && (m = linePattern.exec(source))){
39899 lineStart = m.index;
39900 lineEnd = lineStart + m[0].length;
39901 locator.lineNumber++;
39902 //console.log('line++:',locator,startPos,endPos)
39904 locator.columnNumber = p-lineStart+1;
39908 var linePattern = /.+(?:\r\n?|\n)|.*$/g;
39909 var locator = domBuilder.locator;
39911 var parseStack = [{currentNSMap:defaultNSMapCopy}];
39916 var tagStart = source.indexOf('<',start);
39918 if(!source.substr(start).match(/^\s*$/)){
39919 var doc = domBuilder.document;
39920 var text = doc.createTextNode(source.substr(start));
39921 doc.appendChild(text);
39922 domBuilder.currentElement = text;
39926 if(tagStart>start){
39927 appendText(tagStart);
39929 switch(source.charAt(tagStart+1)){
39931 var end = source.indexOf('>',tagStart+3);
39932 var tagName = source.substring(tagStart+2,end);
39933 var config = parseStack.pop();
39934 var localNSMap = config.localNSMap;
39935 if(config.tagName != tagName){
39936 errorHandler.fatalError("end tag name: "+tagName+' is not match the current start tagName:'+config.tagName );
39938 domBuilder.endElement(config.uri,config.localName,tagName);
39940 for(var prefix in localNSMap){
39941 domBuilder.endPrefixMapping(prefix) ;
39947 case '?':// <?...?>
39948 locator&&position(tagStart);
39949 end = parseInstruction(source,tagStart,domBuilder);
39951 case '!':// <!doctype,<![CDATA,<!--
39952 locator&&position(tagStart);
39953 end = parseDCC(source,tagStart,domBuilder,errorHandler);
39957 locator&&position(tagStart);
39959 var el = new ElementAttributes();
39962 var end = parseElementStartPart(source,tagStart,el,entityReplacer,errorHandler);
39963 var len = el.length;
39967 //attribute position fixed
39968 for(var i = 0;i<len;i++){
39970 position(a.offset);
39971 a.offset = copyLocator(locator,{});
39976 if(!el.closed && fixSelfClosed(source,end,el.tagName,closeMap)){
39978 if(!entityMap.nbsp){
39979 errorHandler.warning('unclosed xml attribute');
39982 appendElement(el,domBuilder,parseStack);
39985 if(el.uri === 'http://www.w3.org/1999/xhtml' && !el.closed){
39986 end = parseHtmlSpecialContent(source,end,el.tagName,entityReplacer,domBuilder);
39992 errorHandler.error('element parse error: '+e);
39998 //TODO: 这里有可能sax回退,有位置错误风险
39999 appendText(Math.max(tagStart,start)+1);
40003 function copyLocator(f,t){
40004 t.lineNumber = f.lineNumber;
40005 t.columnNumber = f.columnNumber;
40010 * @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack);
40011 * @return end of the elementStartPart(end of elementEndPart for selfClosed el)
40013 function parseElementStartPart(source,start,el,entityReplacer,errorHandler){
40017 var s = S_TAG;//status
40019 var c = source.charAt(p);
40022 if(s === S_ATTR){//attrName
40023 attrName = source.slice(start,p);
40025 }else if(s === S_ATTR_S){
40028 //fatalError: equal must after attrName or space after attrName
40029 throw new Error('attribute equal must after attrName');
40034 if(s === S_EQ){//equal
40036 p = source.indexOf(c,start);
40038 value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
40039 el.add(attrName,value,start-1);
40042 //fatalError: no end quot match
40043 throw new Error('attribute value no end \''+c+'\' match');
40045 }else if(s == S_V){
40046 value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
40047 //console.log(attrName,value,start,p)
40048 el.add(attrName,value,start);
40050 errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!');
40054 //fatalError: no equal before
40055 throw new Error('attribute value must after "="');
40061 el.setTagName(source.slice(start,p));
40073 throw new Error("attribute invalid close char('/')")
40076 case ''://end document
40077 //throw new Error('unexpected end of input')
40078 errorHandler.error('unexpected end of input');
40082 el.setTagName(source.slice(start,p));
40087 case S_V://Compatible state
40089 value = source.slice(start,p);
40090 if(value.slice(-1) === '/'){
40092 value = value.slice(0,-1);
40095 if(s === S_ATTR_S){
40099 errorHandler.warning('attribute "'+value+'" missed quot(")!!');
40100 el.add(attrName,value.replace(/&#?\w+;/g,entityReplacer),start);
40102 errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!');
40103 el.add(value,value,start);
40107 throw new Error('attribute value missed!!');
40109 // console.log(tagName,tagNamePattern,tagNamePattern.test(tagName))
40111 /*xml space '\x20' | #x9 | #xD | #xA; */
40115 if(c<= ' '){//space
40118 el.setTagName(source.slice(start,p));//tagName
40122 attrName = source.slice(start,p);
40126 var value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
40127 errorHandler.warning('attribute "'+value+'" missed quot(")!!');
40128 el.add(attrName,value,start);
40140 //S_TAG, S_ATTR, S_EQ, S_V
40141 //S_ATTR_S, S_E, S_S, S_C
40143 //case S_TAG:void();break;
40144 //case S_ATTR:void();break;
40145 //case S_V:void();break;
40147 errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead!!');
40148 el.add(attrName,attrName,start);
40153 errorHandler.warning('attribute space is required"'+attrName+'"!!');
40163 throw new Error("elements closed character '/' and '>' must be connected to");
40171 * @return end of the elementStartPart(end of elementEndPart for selfClosed el)
40173 function appendElement(el,domBuilder,parseStack){
40174 var tagName = el.tagName;
40175 var localNSMap = null;
40176 var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
40180 var qName = a.qName;
40181 var value = a.value;
40182 var nsp = qName.indexOf(':');
40184 var prefix = a.prefix = qName.slice(0,nsp);
40185 var localName = qName.slice(nsp+1);
40186 var nsPrefix = prefix === 'xmlns' && localName;
40190 nsPrefix = qName === 'xmlns' && '';
40192 //can not set prefix,because prefix !== ''
40193 a.localName = localName ;
40194 //prefix == null for no ns prefix attribute
40195 if(nsPrefix !== false){//hack!!
40196 if(localNSMap == null){
40198 //console.log(currentNSMap,0)
40199 _copy(currentNSMap,currentNSMap={});
40200 //console.log(currentNSMap,1)
40202 currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
40203 a.uri = 'http://www.w3.org/2000/xmlns/';
40204 domBuilder.startPrefixMapping(nsPrefix, value);
40210 var prefix = a.prefix;
40211 if(prefix){//no prefix attribute has no namespace
40212 if(prefix === 'xml'){
40213 a.uri = 'http://www.w3.org/XML/1998/namespace';
40214 }if(prefix !== 'xmlns'){
40215 a.uri = currentNSMap[prefix];
40217 //{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)}
40221 var nsp = tagName.indexOf(':');
40223 prefix = el.prefix = tagName.slice(0,nsp);
40224 localName = el.localName = tagName.slice(nsp+1);
40226 prefix = null;//important!!
40227 localName = el.localName = tagName;
40229 //no prefix element has default namespace
40230 var ns = el.uri = currentNSMap[prefix || ''];
40231 domBuilder.startElement(ns,localName,tagName,el);
40232 //endPrefixMapping and startPrefixMapping have not any help for dom builder
40233 //localNSMap = null
40235 domBuilder.endElement(ns,localName,tagName);
40237 for(prefix in localNSMap){
40238 domBuilder.endPrefixMapping(prefix);
40242 el.currentNSMap = currentNSMap;
40243 el.localNSMap = localNSMap;
40244 parseStack.push(el);
40247 function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){
40248 if(/^(?:script|textarea)$/i.test(tagName)){
40249 var elEndStart = source.indexOf('</'+tagName+'>',elStartEnd);
40250 var text = source.substring(elStartEnd+1,elEndStart);
40251 if(/[&<]/.test(text)){
40252 if(/^script$/i.test(tagName)){
40253 //if(!/\]\]>/.test(text)){
40254 //lexHandler.startCDATA();
40255 domBuilder.characters(text,0,text.length);
40256 //lexHandler.endCDATA();
40259 }//}else{//text area
40260 text = text.replace(/&#?\w+;/g,entityReplacer);
40261 domBuilder.characters(text,0,text.length);
40267 return elStartEnd+1;
40269 function fixSelfClosed(source,elStartEnd,tagName,closeMap){
40270 //if(tagName in closeMap){
40271 var pos = closeMap[tagName];
40273 //console.log(tagName)
40274 pos = closeMap[tagName] = source.lastIndexOf('</'+tagName+'>');
40276 return pos<elStartEnd;
40279 function _copy(source,target){
40280 for(var n in source){target[n] = source[n];}
40282 function parseDCC(source,start,domBuilder,errorHandler){//sure start with '<!'
40283 var next= source.charAt(start+2);
40286 if(source.charAt(start + 3) === '-'){
40287 var end = source.indexOf('-->',start+4);
40288 //append comment source.substring(4,end)//<!--
40290 domBuilder.comment(source,start+4,end-start-4);
40293 errorHandler.error("Unclosed comment");
40301 if(source.substr(start+3,6) == 'CDATA['){
40302 var end = source.indexOf(']]>',start+9);
40303 domBuilder.startCDATA();
40304 domBuilder.characters(source,start+9,end-start-9);
40305 domBuilder.endCDATA();
40309 //startDTD(java.lang.String name, java.lang.String publicId, java.lang.String systemId)
40310 var matchs = split(source,start);
40311 var len = matchs.length;
40312 if(len>1 && /!doctype/i.test(matchs[0][0])){
40313 var name = matchs[1][0];
40314 var pubid = len>3 && /^public$/i.test(matchs[2][0]) && matchs[3][0];
40315 var sysid = len>4 && matchs[4][0];
40316 var lastMatch = matchs[len-1];
40317 domBuilder.startDTD(name,pubid && pubid.replace(/^(['"])(.*?)\1$/,'$2'),
40318 sysid && sysid.replace(/^(['"])(.*?)\1$/,'$2'));
40319 domBuilder.endDTD();
40321 return lastMatch.index+lastMatch[0].length
40329 function parseInstruction(source,start,domBuilder){
40330 var end = source.indexOf('?>',start);
40332 var match = source.substring(start,end).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);
40334 var len = match[0].length;
40335 domBuilder.processingInstruction(match[1], match[2]) ;
40347 function ElementAttributes(source){
40350 ElementAttributes.prototype = {
40351 setTagName:function(tagName){
40352 if(!tagNamePattern.test(tagName)){
40353 throw new Error('invalid tagName:'+tagName)
40355 this.tagName = tagName;
40357 add:function(qName,value,offset){
40358 if(!tagNamePattern.test(qName)){
40359 throw new Error('invalid attribute:'+qName)
40361 this[this.length++] = {qName:qName,value:value,offset:offset};
40364 getLocalName:function(i){return this[i].localName},
40365 getOffset:function(i){return this[i].offset},
40366 getQName:function(i){return this[i].qName},
40367 getURI:function(i){return this[i].uri},
40368 getValue:function(i){return this[i].value}
40369 // ,getIndex:function(uri, localName)){
40376 // getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))},
40377 // getType:function(uri,localName){}
40378 // getType:function(i){},
40384 function _set_proto_(thiz,parent){
40385 thiz.__proto__ = parent;
40388 if(!(_set_proto_({},_set_proto_.prototype) instanceof _set_proto_)){
40389 _set_proto_ = function(thiz,parent){
40391 p.prototype = parent;
40393 for(parent in thiz){
40394 p[parent] = thiz[parent];
40400 function split(source,start){
40403 var reg = /'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;
40404 reg.lastIndex = start;
40405 reg.exec(source);//skip <
40406 while(match = reg.exec(source)){
40408 if(match[1])return buf;
40412 if(typeof commonjsRequire == 'function'){
40413 exports.XMLReader = XMLReader;
40417 var dom = createCommonjsModule(function (module, exports) {
40420 * Object DOMException
40421 * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html
40422 * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html
40425 function copy(src,dest){
40431 ^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));?
40432 ^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));?
40434 function _extends(Class,Super){
40435 var pt = Class.prototype;
40437 var ppt = Object.create(Super.prototype);
40438 pt.__proto__ = ppt;
40440 if(!(pt instanceof Super)){
40442 t.prototype = Super.prototype;
40445 Class.prototype = pt = t;
40447 if(pt.constructor != Class){
40448 if(typeof Class != 'function'){
40449 console.error("unknow Class:"+Class);
40451 pt.constructor = Class;
40454 var htmlns = 'http://www.w3.org/1999/xhtml';
40457 var ELEMENT_NODE = NodeType.ELEMENT_NODE = 1;
40458 var ATTRIBUTE_NODE = NodeType.ATTRIBUTE_NODE = 2;
40459 var TEXT_NODE = NodeType.TEXT_NODE = 3;
40460 var CDATA_SECTION_NODE = NodeType.CDATA_SECTION_NODE = 4;
40461 var ENTITY_REFERENCE_NODE = NodeType.ENTITY_REFERENCE_NODE = 5;
40462 var ENTITY_NODE = NodeType.ENTITY_NODE = 6;
40463 var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7;
40464 var COMMENT_NODE = NodeType.COMMENT_NODE = 8;
40465 var DOCUMENT_NODE = NodeType.DOCUMENT_NODE = 9;
40466 var DOCUMENT_TYPE_NODE = NodeType.DOCUMENT_TYPE_NODE = 10;
40467 var DOCUMENT_FRAGMENT_NODE = NodeType.DOCUMENT_FRAGMENT_NODE = 11;
40468 var NOTATION_NODE = NodeType.NOTATION_NODE = 12;
40471 var ExceptionCode = {};
40472 var ExceptionMessage = {};
40473 var INDEX_SIZE_ERR = ExceptionCode.INDEX_SIZE_ERR = ((ExceptionMessage[1]="Index size error"),1);
40474 var DOMSTRING_SIZE_ERR = ExceptionCode.DOMSTRING_SIZE_ERR = ((ExceptionMessage[2]="DOMString size error"),2);
40475 var HIERARCHY_REQUEST_ERR = ExceptionCode.HIERARCHY_REQUEST_ERR = ((ExceptionMessage[3]="Hierarchy request error"),3);
40476 var WRONG_DOCUMENT_ERR = ExceptionCode.WRONG_DOCUMENT_ERR = ((ExceptionMessage[4]="Wrong document"),4);
40477 var INVALID_CHARACTER_ERR = ExceptionCode.INVALID_CHARACTER_ERR = ((ExceptionMessage[5]="Invalid character"),5);
40478 var NO_DATA_ALLOWED_ERR = ExceptionCode.NO_DATA_ALLOWED_ERR = ((ExceptionMessage[6]="No data allowed"),6);
40479 var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = ((ExceptionMessage[7]="No modification allowed"),7);
40480 var NOT_FOUND_ERR = ExceptionCode.NOT_FOUND_ERR = ((ExceptionMessage[8]="Not found"),8);
40481 var NOT_SUPPORTED_ERR = ExceptionCode.NOT_SUPPORTED_ERR = ((ExceptionMessage[9]="Not supported"),9);
40482 var INUSE_ATTRIBUTE_ERR = ExceptionCode.INUSE_ATTRIBUTE_ERR = ((ExceptionMessage[10]="Attribute in use"),10);
40484 var INVALID_STATE_ERR = ExceptionCode.INVALID_STATE_ERR = ((ExceptionMessage[11]="Invalid state"),11);
40485 var SYNTAX_ERR = ExceptionCode.SYNTAX_ERR = ((ExceptionMessage[12]="Syntax error"),12);
40486 var INVALID_MODIFICATION_ERR = ExceptionCode.INVALID_MODIFICATION_ERR = ((ExceptionMessage[13]="Invalid modification"),13);
40487 var NAMESPACE_ERR = ExceptionCode.NAMESPACE_ERR = ((ExceptionMessage[14]="Invalid namespace"),14);
40488 var INVALID_ACCESS_ERR = ExceptionCode.INVALID_ACCESS_ERR = ((ExceptionMessage[15]="Invalid access"),15);
40491 function DOMException(code, message) {
40492 if(message instanceof Error){
40493 var error = message;
40496 Error.call(this, ExceptionMessage[code]);
40497 this.message = ExceptionMessage[code];
40498 if(Error.captureStackTrace) Error.captureStackTrace(this, DOMException);
40501 if(message) this.message = this.message + ": " + message;
40504 DOMException.prototype = Error.prototype;
40505 copy(ExceptionCode,DOMException);
40507 * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177
40508 * The NodeList interface provides the abstraction of an ordered collection of nodes, without defining or constraining how this collection is implemented. NodeList objects in the DOM are live.
40509 * The items in the NodeList are accessible via an integral index, starting from 0.
40511 function NodeList() {
40513 NodeList.prototype = {
40515 * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive.
40520 * Returns the indexth item in the collection. If index is greater than or equal to the number of nodes in the list, this returns null.
40522 * @param index unsigned long
40523 * Index into the collection.
40525 * The node at the indexth position in the NodeList, or null if that is not a valid index.
40527 item: function(index) {
40528 return this[index] || null;
40530 toString:function(){
40531 for(var buf = [], i = 0;i<this.length;i++){
40532 serializeToString(this[i],buf);
40534 return buf.join('');
40537 function LiveNodeList(node,refresh){
40539 this._refresh = refresh;
40540 _updateLiveList(this);
40542 function _updateLiveList(list){
40543 var inc = list._node._inc || list._node.ownerDocument._inc;
40544 if(list._inc != inc){
40545 var ls = list._refresh(list._node);
40546 //console.log(ls.length)
40547 __set__(list,'length',ls.length);
40552 LiveNodeList.prototype.item = function(i){
40553 _updateLiveList(this);
40557 _extends(LiveNodeList,NodeList);
40560 * Objects implementing the NamedNodeMap interface are used to represent collections of nodes that can be accessed by name. Note that NamedNodeMap does not inherit from NodeList; NamedNodeMaps are not maintained in any particular order. Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal index, but this is simply to allow convenient enumeration of the contents of a NamedNodeMap, and does not imply that the DOM specifies an order to these Nodes.
40561 * NamedNodeMap objects in the DOM are live.
40562 * used for attributes or DocumentType entities
40564 function NamedNodeMap() {
40567 function _findNodeIndex(list,node){
40568 var i = list.length;
40570 if(list[i] === node){return i}
40574 function _addNamedNode(el,list,newAttr,oldAttr){
40576 list[_findNodeIndex(list,oldAttr)] = newAttr;
40578 list[list.length++] = newAttr;
40581 newAttr.ownerElement = el;
40582 var doc = el.ownerDocument;
40584 oldAttr && _onRemoveAttribute(doc,el,oldAttr);
40585 _onAddAttribute(doc,el,newAttr);
40589 function _removeNamedNode(el,list,attr){
40590 var i = _findNodeIndex(list,attr);
40592 var lastIndex = list.length-1;
40593 while(i<lastIndex){
40594 list[i] = list[++i];
40596 list.length = lastIndex;
40598 var doc = el.ownerDocument;
40600 _onRemoveAttribute(doc,el,attr);
40601 attr.ownerElement = null;
40605 throw DOMException(NOT_FOUND_ERR,new Error())
40608 NamedNodeMap.prototype = {
40610 item:NodeList.prototype.item,
40611 getNamedItem: function(key) {
40612 // if(key.indexOf(':')>0 || key == 'xmlns'){
40615 var i = this.length;
40617 var attr = this[i];
40618 if(attr.nodeName == key){
40623 setNamedItem: function(attr) {
40624 var el = attr.ownerElement;
40625 if(el && el!=this._ownerElement){
40626 throw new DOMException(INUSE_ATTRIBUTE_ERR);
40628 var oldAttr = this.getNamedItem(attr.nodeName);
40629 _addNamedNode(this._ownerElement,this,attr,oldAttr);
40633 setNamedItemNS: function(attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR
40634 var el = attr.ownerElement, oldAttr;
40635 if(el && el!=this._ownerElement){
40636 throw new DOMException(INUSE_ATTRIBUTE_ERR);
40638 oldAttr = this.getNamedItemNS(attr.namespaceURI,attr.localName);
40639 _addNamedNode(this._ownerElement,this,attr,oldAttr);
40644 removeNamedItem: function(key) {
40645 var attr = this.getNamedItem(key);
40646 _removeNamedNode(this._ownerElement,this,attr);
40650 },// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR
40653 removeNamedItemNS:function(namespaceURI,localName){
40654 var attr = this.getNamedItemNS(namespaceURI,localName);
40655 _removeNamedNode(this._ownerElement,this,attr);
40658 getNamedItemNS: function(namespaceURI, localName) {
40659 var i = this.length;
40661 var node = this[i];
40662 if(node.localName == localName && node.namespaceURI == namespaceURI){
40670 * @see http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490
40672 function DOMImplementation(/* Object */ features) {
40673 this._features = {};
40675 for (var feature in features) {
40676 this._features = features[feature];
40681 DOMImplementation.prototype = {
40682 hasFeature: function(/* string */ feature, /* string */ version) {
40683 var versions = this._features[feature.toLowerCase()];
40684 if (versions && (!version || version in versions)) {
40690 // Introduced in DOM Level 2:
40691 createDocument:function(namespaceURI, qualifiedName, doctype){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR,WRONG_DOCUMENT_ERR
40692 var doc = new Document();
40693 doc.implementation = this;
40694 doc.childNodes = new NodeList();
40695 doc.doctype = doctype;
40697 doc.appendChild(doctype);
40700 var root = doc.createElementNS(namespaceURI,qualifiedName);
40701 doc.appendChild(root);
40705 // Introduced in DOM Level 2:
40706 createDocumentType:function(qualifiedName, publicId, systemId){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR
40707 var node = new DocumentType();
40708 node.name = qualifiedName;
40709 node.nodeName = qualifiedName;
40710 node.publicId = publicId;
40711 node.systemId = systemId;
40712 // Introduced in DOM Level 2:
40713 //readonly attribute DOMString internalSubset;
40716 // readonly attribute NamedNodeMap entities;
40717 // readonly attribute NamedNodeMap notations;
40724 * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247
40733 previousSibling : null,
40734 nextSibling : null,
40738 ownerDocument : null,
40740 namespaceURI : null,
40743 // Modified in DOM Level 2:
40744 insertBefore:function(newChild, refChild){//raises
40745 return _insertBefore(this,newChild,refChild);
40747 replaceChild:function(newChild, oldChild){//raises
40748 this.insertBefore(newChild,oldChild);
40750 this.removeChild(oldChild);
40753 removeChild:function(oldChild){
40754 return _removeChild(this,oldChild);
40756 appendChild:function(newChild){
40757 return this.insertBefore(newChild,null);
40759 hasChildNodes:function(){
40760 return this.firstChild != null;
40762 cloneNode:function(deep){
40763 return cloneNode(this.ownerDocument||this,this,deep);
40765 // Modified in DOM Level 2:
40766 normalize:function(){
40767 var child = this.firstChild;
40769 var next = child.nextSibling;
40770 if(next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE){
40771 this.removeChild(next);
40772 child.appendData(next.data);
40779 // Introduced in DOM Level 2:
40780 isSupported:function(feature, version){
40781 return this.ownerDocument.implementation.hasFeature(feature,version);
40783 // Introduced in DOM Level 2:
40784 hasAttributes:function(){
40785 return this.attributes.length>0;
40787 lookupPrefix:function(namespaceURI){
40790 var map = el._nsMap;
40794 if(map[n] == namespaceURI){
40799 el = el.nodeType == 2?el.ownerDocument : el.parentNode;
40803 // Introduced in DOM Level 3:
40804 lookupNamespaceURI:function(prefix){
40807 var map = el._nsMap;
40811 return map[prefix] ;
40814 el = el.nodeType == 2?el.ownerDocument : el.parentNode;
40818 // Introduced in DOM Level 3:
40819 isDefaultNamespace:function(namespaceURI){
40820 var prefix = this.lookupPrefix(namespaceURI);
40821 return prefix == null;
40826 function _xmlEncoder(c){
40827 return c == '<' && '<' ||
40828 c == '>' && '>' ||
40829 c == '&' && '&' ||
40830 c == '"' && '"' ||
40831 '&#'+c.charCodeAt()+';'
40835 copy(NodeType,Node);
40836 copy(NodeType,Node.prototype);
40839 * @param callback return true for continue,false for break
40840 * @return boolean true: break visit;
40842 function _visitNode(node,callback){
40843 if(callback(node)){
40846 if(node = node.firstChild){
40848 if(_visitNode(node,callback)){return true}
40849 }while(node=node.nextSibling)
40855 function Document(){
40857 function _onAddAttribute(doc,el,newAttr){
40859 var ns = newAttr.namespaceURI;
40860 if(ns == 'http://www.w3.org/2000/xmlns/'){
40862 el._nsMap[newAttr.prefix?newAttr.localName:''] = newAttr.value;
40865 function _onRemoveAttribute(doc,el,newAttr,remove){
40867 var ns = newAttr.namespaceURI;
40868 if(ns == 'http://www.w3.org/2000/xmlns/'){
40870 delete el._nsMap[newAttr.prefix?newAttr.localName:''];
40873 function _onUpdateChild(doc,el,newChild){
40874 if(doc && doc._inc){
40876 //update childNodes
40877 var cs = el.childNodes;
40879 cs[cs.length++] = newChild;
40882 var child = el.firstChild;
40886 child =child.nextSibling;
40897 * writeable properties:
40898 * nodeValue,Attr:value,CharacterData:data
40901 function _removeChild(parentNode,child){
40902 var previous = child.previousSibling;
40903 var next = child.nextSibling;
40905 previous.nextSibling = next;
40907 parentNode.firstChild = next;
40910 next.previousSibling = previous;
40912 parentNode.lastChild = previous;
40914 _onUpdateChild(parentNode.ownerDocument,parentNode);
40918 * preformance key(refChild == null)
40920 function _insertBefore(parentNode,newChild,nextChild){
40921 var cp = newChild.parentNode;
40923 cp.removeChild(newChild);//remove and update
40925 if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
40926 var newFirst = newChild.firstChild;
40927 if (newFirst == null) {
40930 var newLast = newChild.lastChild;
40932 newFirst = newLast = newChild;
40934 var pre = nextChild ? nextChild.previousSibling : parentNode.lastChild;
40936 newFirst.previousSibling = pre;
40937 newLast.nextSibling = nextChild;
40941 pre.nextSibling = newFirst;
40943 parentNode.firstChild = newFirst;
40945 if(nextChild == null){
40946 parentNode.lastChild = newLast;
40948 nextChild.previousSibling = newLast;
40951 newFirst.parentNode = parentNode;
40952 }while(newFirst !== newLast && (newFirst= newFirst.nextSibling))
40953 _onUpdateChild(parentNode.ownerDocument||parentNode,parentNode);
40954 //console.log(parentNode.lastChild.nextSibling == null)
40955 if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) {
40956 newChild.firstChild = newChild.lastChild = null;
40960 function _appendSingleChild(parentNode,newChild){
40961 var cp = newChild.parentNode;
40963 var pre = parentNode.lastChild;
40964 cp.removeChild(newChild);//remove and update
40965 var pre = parentNode.lastChild;
40967 var pre = parentNode.lastChild;
40968 newChild.parentNode = parentNode;
40969 newChild.previousSibling = pre;
40970 newChild.nextSibling = null;
40972 pre.nextSibling = newChild;
40974 parentNode.firstChild = newChild;
40976 parentNode.lastChild = newChild;
40977 _onUpdateChild(parentNode.ownerDocument,parentNode,newChild);
40979 //console.log("__aa",parentNode.lastChild.nextSibling == null)
40981 Document.prototype = {
40982 //implementation : null,
40983 nodeName : '#document',
40984 nodeType : DOCUMENT_NODE,
40986 documentElement : null,
40989 insertBefore : function(newChild, refChild){//raises
40990 if(newChild.nodeType == DOCUMENT_FRAGMENT_NODE){
40991 var child = newChild.firstChild;
40993 var next = child.nextSibling;
40994 this.insertBefore(child,refChild);
40999 if(this.documentElement == null && newChild.nodeType == 1){
41000 this.documentElement = newChild;
41003 return _insertBefore(this,newChild,refChild),(newChild.ownerDocument = this),newChild;
41005 removeChild : function(oldChild){
41006 if(this.documentElement == oldChild){
41007 this.documentElement = null;
41009 return _removeChild(this,oldChild);
41011 // Introduced in DOM Level 2:
41012 importNode : function(importedNode,deep){
41013 return importNode(this,importedNode,deep);
41015 // Introduced in DOM Level 2:
41016 getElementById : function(id){
41018 _visitNode(this.documentElement,function(node){
41019 if(node.nodeType == 1){
41020 if(node.getAttribute('id') == id){
41029 //document factory method:
41030 createElement : function(tagName){
41031 var node = new Element();
41032 node.ownerDocument = this;
41033 node.nodeName = tagName;
41034 node.tagName = tagName;
41035 node.childNodes = new NodeList();
41036 var attrs = node.attributes = new NamedNodeMap();
41037 attrs._ownerElement = node;
41040 createDocumentFragment : function(){
41041 var node = new DocumentFragment();
41042 node.ownerDocument = this;
41043 node.childNodes = new NodeList();
41046 createTextNode : function(data){
41047 var node = new Text();
41048 node.ownerDocument = this;
41049 node.appendData(data);
41052 createComment : function(data){
41053 var node = new Comment();
41054 node.ownerDocument = this;
41055 node.appendData(data);
41058 createCDATASection : function(data){
41059 var node = new CDATASection();
41060 node.ownerDocument = this;
41061 node.appendData(data);
41064 createProcessingInstruction : function(target,data){
41065 var node = new ProcessingInstruction();
41066 node.ownerDocument = this;
41067 node.tagName = node.target = target;
41068 node.nodeValue= node.data = data;
41071 createAttribute : function(name){
41072 var node = new Attr();
41073 node.ownerDocument = this;
41075 node.nodeName = name;
41076 node.localName = name;
41077 node.specified = true;
41080 createEntityReference : function(name){
41081 var node = new EntityReference();
41082 node.ownerDocument = this;
41083 node.nodeName = name;
41086 // Introduced in DOM Level 2:
41087 createElementNS : function(namespaceURI,qualifiedName){
41088 var node = new Element();
41089 var pl = qualifiedName.split(':');
41090 var attrs = node.attributes = new NamedNodeMap();
41091 node.childNodes = new NodeList();
41092 node.ownerDocument = this;
41093 node.nodeName = qualifiedName;
41094 node.tagName = qualifiedName;
41095 node.namespaceURI = namespaceURI;
41096 if(pl.length == 2){
41097 node.prefix = pl[0];
41098 node.localName = pl[1];
41100 //el.prefix = null;
41101 node.localName = qualifiedName;
41103 attrs._ownerElement = node;
41106 // Introduced in DOM Level 2:
41107 createAttributeNS : function(namespaceURI,qualifiedName){
41108 var node = new Attr();
41109 var pl = qualifiedName.split(':');
41110 node.ownerDocument = this;
41111 node.nodeName = qualifiedName;
41112 node.name = qualifiedName;
41113 node.namespaceURI = namespaceURI;
41114 node.specified = true;
41115 if(pl.length == 2){
41116 node.prefix = pl[0];
41117 node.localName = pl[1];
41119 //el.prefix = null;
41120 node.localName = qualifiedName;
41125 _extends(Document,Node);
41128 function Element() {
41131 Element.prototype = {
41132 nodeType : ELEMENT_NODE,
41133 hasAttribute : function(name){
41134 return this.getAttributeNode(name)!=null;
41136 getAttribute : function(name){
41137 var attr = this.getAttributeNode(name);
41138 return attr && attr.value || '';
41140 getAttributeNode : function(name){
41141 return this.attributes.getNamedItem(name);
41143 setAttribute : function(name, value){
41144 var attr = this.ownerDocument.createAttribute(name);
41145 attr.value = attr.nodeValue = "" + value;
41146 this.setAttributeNode(attr);
41148 removeAttribute : function(name){
41149 var attr = this.getAttributeNode(name);
41150 attr && this.removeAttributeNode(attr);
41153 //four real opeartion method
41154 appendChild:function(newChild){
41155 if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
41156 return this.insertBefore(newChild,null);
41158 return _appendSingleChild(this,newChild);
41161 setAttributeNode : function(newAttr){
41162 return this.attributes.setNamedItem(newAttr);
41164 setAttributeNodeNS : function(newAttr){
41165 return this.attributes.setNamedItemNS(newAttr);
41167 removeAttributeNode : function(oldAttr){
41168 return this.attributes.removeNamedItem(oldAttr.nodeName);
41170 //get real attribute name,and remove it by removeAttributeNode
41171 removeAttributeNS : function(namespaceURI, localName){
41172 var old = this.getAttributeNodeNS(namespaceURI, localName);
41173 old && this.removeAttributeNode(old);
41176 hasAttributeNS : function(namespaceURI, localName){
41177 return this.getAttributeNodeNS(namespaceURI, localName)!=null;
41179 getAttributeNS : function(namespaceURI, localName){
41180 var attr = this.getAttributeNodeNS(namespaceURI, localName);
41181 return attr && attr.value || '';
41183 setAttributeNS : function(namespaceURI, qualifiedName, value){
41184 var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
41185 attr.value = attr.nodeValue = "" + value;
41186 this.setAttributeNode(attr);
41188 getAttributeNodeNS : function(namespaceURI, localName){
41189 return this.attributes.getNamedItemNS(namespaceURI, localName);
41192 getElementsByTagName : function(tagName){
41193 return new LiveNodeList(this,function(base){
41195 _visitNode(base,function(node){
41196 if(node !== base && node.nodeType == ELEMENT_NODE && (tagName === '*' || node.tagName == tagName)){
41203 getElementsByTagNameNS : function(namespaceURI, localName){
41204 return new LiveNodeList(this,function(base){
41206 _visitNode(base,function(node){
41207 if(node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === '*' || node.namespaceURI === namespaceURI) && (localName === '*' || node.localName == localName)){
41215 Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName;
41216 Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS;
41219 _extends(Element,Node);
41222 Attr.prototype.nodeType = ATTRIBUTE_NODE;
41223 _extends(Attr,Node);
41226 function CharacterData() {
41228 CharacterData.prototype = {
41230 substringData : function(offset, count) {
41231 return this.data.substring(offset, offset+count);
41233 appendData: function(text) {
41234 text = this.data+text;
41235 this.nodeValue = this.data = text;
41236 this.length = text.length;
41238 insertData: function(offset,text) {
41239 this.replaceData(offset,0,text);
41242 appendChild:function(newChild){
41243 //if(!(newChild instanceof CharacterData)){
41244 throw new Error(ExceptionMessage[3])
41246 return Node.prototype.appendChild.apply(this,arguments)
41248 deleteData: function(offset, count) {
41249 this.replaceData(offset,count,"");
41251 replaceData: function(offset, count, text) {
41252 var start = this.data.substring(0,offset);
41253 var end = this.data.substring(offset+count);
41254 text = start + text + end;
41255 this.nodeValue = this.data = text;
41256 this.length = text.length;
41259 _extends(CharacterData,Node);
41263 nodeName : "#text",
41264 nodeType : TEXT_NODE,
41265 splitText : function(offset) {
41266 var text = this.data;
41267 var newText = text.substring(offset);
41268 text = text.substring(0, offset);
41269 this.data = this.nodeValue = text;
41270 this.length = text.length;
41271 var newNode = this.ownerDocument.createTextNode(newText);
41272 if(this.parentNode){
41273 this.parentNode.insertBefore(newNode, this.nextSibling);
41278 _extends(Text,CharacterData);
41279 function Comment() {
41281 Comment.prototype = {
41282 nodeName : "#comment",
41283 nodeType : COMMENT_NODE
41285 _extends(Comment,CharacterData);
41287 function CDATASection() {
41289 CDATASection.prototype = {
41290 nodeName : "#cdata-section",
41291 nodeType : CDATA_SECTION_NODE
41293 _extends(CDATASection,CharacterData);
41296 function DocumentType() {
41298 DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE;
41299 _extends(DocumentType,Node);
41301 function Notation() {
41303 Notation.prototype.nodeType = NOTATION_NODE;
41304 _extends(Notation,Node);
41306 function Entity() {
41308 Entity.prototype.nodeType = ENTITY_NODE;
41309 _extends(Entity,Node);
41311 function EntityReference() {
41313 EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE;
41314 _extends(EntityReference,Node);
41316 function DocumentFragment() {
41318 DocumentFragment.prototype.nodeName = "#document-fragment";
41319 DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE;
41320 _extends(DocumentFragment,Node);
41323 function ProcessingInstruction() {
41325 ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE;
41326 _extends(ProcessingInstruction,Node);
41327 function XMLSerializer(){}
41328 XMLSerializer.prototype.serializeToString = function(node,attributeSorter){
41329 return node.toString(attributeSorter);
41331 Node.prototype.toString =function(attributeSorter){
41333 serializeToString(this,buf,attributeSorter);
41334 return buf.join('');
41336 function serializeToString(node,buf,attributeSorter,isHTML){
41337 switch(node.nodeType){
41339 var attrs = node.attributes;
41340 var len = attrs.length;
41341 var child = node.firstChild;
41342 var nodeName = node.tagName;
41343 isHTML = (htmlns === node.namespaceURI) ||isHTML;
41344 buf.push('<',nodeName);
41345 if(attributeSorter){
41346 buf.sort.apply(attrs, attributeSorter);
41348 for(var i=0;i<len;i++){
41349 serializeToString(attrs.item(i),buf,attributeSorter,isHTML);
41351 if(child || isHTML && !/^(?:meta|link|img|br|hr|input|button)$/i.test(nodeName)){
41353 //if is cdata child node
41354 if(isHTML && /^script$/i.test(nodeName)){
41356 buf.push(child.data);
41360 serializeToString(child,buf,attributeSorter,isHTML);
41361 child = child.nextSibling;
41364 buf.push('</',nodeName,'>');
41369 case DOCUMENT_NODE:
41370 case DOCUMENT_FRAGMENT_NODE:
41371 var child = node.firstChild;
41373 serializeToString(child,buf,attributeSorter,isHTML);
41374 child = child.nextSibling;
41377 case ATTRIBUTE_NODE:
41378 return buf.push(' ',node.name,'="',node.value.replace(/[<&"]/g,_xmlEncoder),'"');
41380 return buf.push(node.data.replace(/[<&]/g,_xmlEncoder));
41381 case CDATA_SECTION_NODE:
41382 return buf.push( '<![CDATA[',node.data,']]>');
41384 return buf.push( "<!--",node.data,"-->");
41385 case DOCUMENT_TYPE_NODE:
41386 var pubid = node.publicId;
41387 var sysid = node.systemId;
41388 buf.push('<!DOCTYPE ',node.name);
41390 buf.push(' PUBLIC "',pubid);
41391 if (sysid && sysid!='.') {
41392 buf.push( '" "',sysid);
41395 }else if(sysid && sysid!='.'){
41396 buf.push(' SYSTEM "',sysid,'">');
41398 var sub = node.internalSubset;
41400 buf.push(" [",sub,"]");
41405 case PROCESSING_INSTRUCTION_NODE:
41406 return buf.push( "<?",node.target," ",node.data,"?>");
41407 case ENTITY_REFERENCE_NODE:
41408 return buf.push( '&',node.nodeName,';');
41409 //case ENTITY_NODE:
41410 //case NOTATION_NODE:
41412 buf.push('??',node.nodeName);
41415 function importNode(doc,node,deep){
41417 switch (node.nodeType) {
41419 node2 = node.cloneNode(false);
41420 node2.ownerDocument = doc;
41421 //var attrs = node2.attributes;
41422 //var len = attrs.length;
41423 //for(var i=0;i<len;i++){
41424 //node2.setAttributeNodeNS(importNode(doc,attrs.item(i),deep));
41426 case DOCUMENT_FRAGMENT_NODE:
41428 case ATTRIBUTE_NODE:
41431 //case ENTITY_REFERENCE_NODE:
41432 //case PROCESSING_INSTRUCTION_NODE:
41433 ////case TEXT_NODE:
41434 //case CDATA_SECTION_NODE:
41435 //case COMMENT_NODE:
41438 //case DOCUMENT_NODE:
41439 //case DOCUMENT_TYPE_NODE:
41440 //cannot be imported.
41441 //case ENTITY_NODE:
41442 //case NOTATION_NODE:
41443 //can not hit in level3
41447 node2 = node.cloneNode(false);//false
41449 node2.ownerDocument = doc;
41450 node2.parentNode = null;
41452 var child = node.firstChild;
41454 node2.appendChild(importNode(doc,child,deep));
41455 child = child.nextSibling;
41461 //var _relationMap = {firstChild:1,lastChild:1,previousSibling:1,nextSibling:1,
41462 // attributes:1,childNodes:1,parentNode:1,documentElement:1,doctype,};
41463 function cloneNode(doc,node,deep){
41464 var node2 = new node.constructor();
41465 for(var n in node){
41467 if(typeof v != 'object' ){
41473 if(node.childNodes){
41474 node2.childNodes = new NodeList();
41476 node2.ownerDocument = doc;
41477 switch (node2.nodeType) {
41479 var attrs = node.attributes;
41480 var attrs2 = node2.attributes = new NamedNodeMap();
41481 var len = attrs.length;
41482 attrs2._ownerElement = node2;
41483 for(var i=0;i<len;i++){
41484 node2.setAttributeNode(cloneNode(doc,attrs.item(i),true));
41487 case ATTRIBUTE_NODE:
41491 var child = node.firstChild;
41493 node2.appendChild(cloneNode(doc,child,deep));
41494 child = child.nextSibling;
41500 function __set__(object,key,value){
41501 object[key] = value;
41505 if(Object.defineProperty){
41506 Object.defineProperty(LiveNodeList.prototype,'length',{
41508 _updateLiveList(this);
41509 return this.$$length;
41512 Object.defineProperty(Node.prototype,'textContent',{
41514 return getTextContent(this);
41516 set:function(data){
41517 switch(this.nodeType){
41520 while(this.firstChild){
41521 this.removeChild(this.firstChild);
41523 if(data || String(data)){
41524 this.appendChild(this.ownerDocument.createTextNode(data));
41530 this.value = value;
41531 this.nodeValue = data;
41536 function getTextContent(node){
41537 switch(node.nodeType){
41541 node = node.firstChild;
41543 if(node.nodeType!==7 && node.nodeType !==8){
41544 buf.push(getTextContent(node));
41546 node = node.nextSibling;
41548 return buf.join('');
41550 return node.nodeValue;
41553 __set__ = function(object,key,value){
41554 //console.log(value)
41555 object['$$'+key] = value;
41561 if(typeof commonjsRequire == 'function'){
41562 exports.DOMImplementation = DOMImplementation;
41563 exports.XMLSerializer = XMLSerializer;
41567 var domParser = createCommonjsModule(function (module, exports) {
41568 function DOMParser(options){
41569 this.options = options ||{locator:{}};
41572 DOMParser.prototype.parseFromString = function(source,mimeType){
41573 var options = this.options;
41574 var sax$$1 = new XMLReader();
41575 var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler
41576 var errorHandler = options.errorHandler;
41577 var locator = options.locator;
41578 var defaultNSMap = options.xmlns||{};
41579 var entityMap = {'lt':'<','gt':'>','amp':'&','quot':'"','apos':"'"};
41581 domBuilder.setDocumentLocator(locator);
41584 sax$$1.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator);
41585 sax$$1.domBuilder = options.domBuilder || domBuilder;
41586 if(/\/x?html?$/.test(mimeType)){
41587 entityMap.nbsp = '\xa0';
41588 entityMap.copy = '\xa9';
41589 defaultNSMap['']= 'http://www.w3.org/1999/xhtml';
41591 defaultNSMap.xml = defaultNSMap.xml || 'http://www.w3.org/XML/1998/namespace';
41593 sax$$1.parse(source,defaultNSMap,entityMap);
41595 sax$$1.errorHandler.error("invalid document source");
41597 return domBuilder.document;
41599 function buildErrorHandler(errorImpl,domBuilder,locator){
41601 if(domBuilder instanceof DOMHandler){
41604 errorImpl = domBuilder ;
41606 var errorHandler = {};
41607 var isCallback = errorImpl instanceof Function;
41608 locator = locator||{};
41609 function build(key){
41610 var fn = errorImpl[key];
41611 if(!fn && isCallback){
41612 fn = errorImpl.length == 2?function(msg){errorImpl(key,msg);}:errorImpl;
41614 errorHandler[key] = fn && function(msg){
41615 fn('[xmldom '+key+']\t'+msg+_locator(locator));
41620 build('fatalError');
41621 return errorHandler;
41624 //console.log('#\n\n\n\n\n\n\n####')
41626 * +ContentHandler+ErrorHandler
41627 * +LexicalHandler+EntityResolver2
41628 * -DeclHandler-DTDHandler
41630 * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler
41631 * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2
41632 * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html
41634 function DOMHandler() {
41635 this.cdata = false;
41637 function position(locator,node){
41638 node.lineNumber = locator.lineNumber;
41639 node.columnNumber = locator.columnNumber;
41642 * @see org.xml.sax.ContentHandler#startDocument
41643 * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
41645 DOMHandler.prototype = {
41646 startDocument : function() {
41647 this.document = new DOMImplementation().createDocument(null, null, null);
41648 if (this.locator) {
41649 this.document.documentURI = this.locator.systemId;
41652 startElement:function(namespaceURI, localName, qName, attrs) {
41653 var doc = this.document;
41654 var el = doc.createElementNS(namespaceURI, qName||localName);
41655 var len = attrs.length;
41656 appendElement(this, el);
41657 this.currentElement = el;
41659 this.locator && position(this.locator,el);
41660 for (var i = 0 ; i < len; i++) {
41661 var namespaceURI = attrs.getURI(i);
41662 var value = attrs.getValue(i);
41663 var qName = attrs.getQName(i);
41664 var attr = doc.createAttributeNS(namespaceURI, qName);
41665 if( attr.getOffset){
41666 position(attr.getOffset(1),attr);
41668 attr.value = attr.nodeValue = value;
41669 el.setAttributeNode(attr);
41672 endElement:function(namespaceURI, localName, qName) {
41673 var current = this.currentElement;
41674 var tagName = current.tagName;
41675 this.currentElement = current.parentNode;
41677 startPrefixMapping:function(prefix, uri) {
41679 endPrefixMapping:function(prefix) {
41681 processingInstruction:function(target, data) {
41682 var ins = this.document.createProcessingInstruction(target, data);
41683 this.locator && position(this.locator,ins);
41684 appendElement(this, ins);
41686 ignorableWhitespace:function(ch, start, length) {
41688 characters:function(chars, start, length) {
41689 chars = _toString.apply(this,arguments);
41690 //console.log(chars)
41691 if(this.currentElement && chars){
41693 var charNode = this.document.createCDATASection(chars);
41694 this.currentElement.appendChild(charNode);
41696 var charNode = this.document.createTextNode(chars);
41697 this.currentElement.appendChild(charNode);
41699 this.locator && position(this.locator,charNode);
41702 skippedEntity:function(name) {
41704 endDocument:function() {
41705 this.document.normalize();
41707 setDocumentLocator:function (locator) {
41708 if(this.locator = locator){// && !('lineNumber' in locator)){
41709 locator.lineNumber = 0;
41713 comment:function(chars, start, length) {
41714 chars = _toString.apply(this,arguments);
41715 var comm = this.document.createComment(chars);
41716 this.locator && position(this.locator,comm);
41717 appendElement(this, comm);
41720 startCDATA:function() {
41721 //used in characters() methods
41724 endCDATA:function() {
41725 this.cdata = false;
41728 startDTD:function(name, publicId, systemId) {
41729 var impl = this.document.implementation;
41730 if (impl && impl.createDocumentType) {
41731 var dt = impl.createDocumentType(name, publicId, systemId);
41732 this.locator && position(this.locator,dt);
41733 appendElement(this, dt);
41737 * @see org.xml.sax.ErrorHandler
41738 * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
41740 warning:function(error) {
41741 console.warn('[xmldom warning]\t'+error,_locator(this.locator));
41743 error:function(error) {
41744 console.error('[xmldom error]\t'+error,_locator(this.locator));
41746 fatalError:function(error) {
41747 console.error('[xmldom fatalError]\t'+error,_locator(this.locator));
41751 function _locator(l){
41753 return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']'
41756 function _toString(chars,start,length){
41757 if(typeof chars == 'string'){
41758 return chars.substr(start,length)
41759 }else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)")
41760 if(chars.length >= start+length || start){
41761 return new java.lang.String(chars,start,length)+'';
41768 * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html
41769 * used method of org.xml.sax.ext.LexicalHandler:
41770 * #comment(chars, start, length)
41773 * #startDTD(name, publicId, systemId)
41776 * IGNORED method of org.xml.sax.ext.LexicalHandler:
41778 * #startEntity(name)
41782 * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html
41783 * IGNORED method of org.xml.sax.ext.DeclHandler
41784 * #attributeDecl(eName, aName, type, mode, value)
41785 * #elementDecl(name, model)
41786 * #externalEntityDecl(name, publicId, systemId)
41787 * #internalEntityDecl(name, value)
41788 * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html
41789 * IGNORED method of org.xml.sax.EntityResolver2
41790 * #resolveEntity(String name,String publicId,String baseURI,String systemId)
41791 * #resolveEntity(publicId, systemId)
41792 * #getExternalSubset(name, baseURI)
41793 * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html
41794 * IGNORED method of org.xml.sax.DTDHandler
41795 * #notationDecl(name, publicId, systemId) {};
41796 * #unparsedEntityDecl(name, publicId, systemId, notationName) {};
41798 "endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){
41799 DOMHandler.prototype[key] = function(){return null};
41802 /* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */
41803 function appendElement (hander,node) {
41804 if (!hander.currentElement) {
41805 hander.document.appendChild(node);
41807 hander.currentElement.appendChild(node);
41809 }//appendChild and setAttributeNS are preformance key
41811 if(typeof commonjsRequire == 'function'){
41812 var XMLReader = sax.XMLReader;
41813 var DOMImplementation = exports.DOMImplementation = dom.DOMImplementation;
41814 exports.XMLSerializer = dom.XMLSerializer ;
41815 exports.DOMParser = DOMParser;
41819 var togeojson = createCommonjsModule(function (module, exports) {
41820 var toGeoJSON = (function() {
41823 var removeSpace = /\s*/g,
41824 trimSpace = /^\s*|\s*$/g,
41825 splitSpace = /\s+/;
41826 // generate a short, numeric hash of a string
41827 function okhash(x) {
41828 if (!x || !x.length) return 0;
41829 for (var i = 0, h = 0; i < x.length; i++) {
41830 h = ((h << 5) - h) + x.charCodeAt(i) | 0;
41833 // all Y children of X
41834 function get(x, y) { return x.getElementsByTagName(y); }
41835 function attr(x, y) { return x.getAttribute(y); }
41836 function attrf(x, y) { return parseFloat(attr(x, y)); }
41837 // one Y child of X, if any, otherwise null
41838 function get1(x, y) { var n = get(x, y); return n.length ? n[0] : null; }
41839 // https://developer.mozilla.org/en-US/docs/Web/API/Node.normalize
41840 function norm(el) { if (el.normalize) { el.normalize(); } return el; }
41841 // cast array x into numbers
41842 function numarray(x) {
41843 for (var j = 0, o = []; j < x.length; j++) { o[j] = parseFloat(x[j]); }
41846 // get the content of a text node, if any
41847 function nodeVal(x) {
41848 if (x) { norm(x); }
41849 return (x && x.textContent) || '';
41851 // get the contents of multiple text nodes, if present
41852 function getMulti(x, ys) {
41854 for (k = 0; k < ys.length; k++) {
41855 n = get1(x, ys[k]);
41856 if (n) o[ys[k]] = nodeVal(n);
41860 // add properties of Y to X, overwriting if present in both
41861 function extend(x, y) { for (var k in y) x[k] = y[k]; }
41862 // get one coordinate from a coordinate array, if any
41863 function coord1(v) { return numarray(v.replace(removeSpace, '').split(',')); }
41864 // get all coordinates from a coordinate array as [[],[]]
41865 function coord(v) {
41866 var coords = v.replace(trimSpace, '').split(splitSpace),
41868 for (var i = 0; i < coords.length; i++) {
41869 o.push(coord1(coords[i]));
41873 function coordPair(x) {
41874 var ll = [attrf(x, 'lon'), attrf(x, 'lat')],
41875 ele = get1(x, 'ele'),
41876 // handle namespaced attribute in browser
41877 heartRate = get1(x, 'gpxtpx:hr') || get1(x, 'hr'),
41878 time = get1(x, 'time'),
41881 e = parseFloat(nodeVal(ele));
41888 time: time ? nodeVal(time) : null,
41889 heartRate: heartRate ? parseFloat(nodeVal(heartRate)) : null
41893 // create a new feature collection parent object
41896 type: 'FeatureCollection',
41902 if (typeof XMLSerializer !== 'undefined') {
41903 /* istanbul ignore next */
41904 serializer = new XMLSerializer();
41905 // only require xmldom in a node environment
41906 } else if (typeof exports === 'object' && typeof process === 'object' && !process.browser) {
41907 serializer = new (domParser.XMLSerializer)();
41909 function xml2str(str) {
41910 // IE9 will create a new XMLSerializer but it'll crash immediately.
41911 // This line is ignored because we don't run coverage tests in IE9
41912 /* istanbul ignore next */
41913 if (str.xml !== undefined) return str.xml;
41914 return serializer.serializeToString(str);
41918 kml: function(doc) {
41921 // styleindex keeps track of hashed styles in order to match features
41922 styleIndex = {}, styleByHash = {},
41923 // stylemapindex keeps track of style maps to expose in properties
41924 styleMapIndex = {},
41925 // atomic geospatial types supported by KML - MultiGeometry is
41926 // handled separately
41927 geotypes = ['Polygon', 'LineString', 'Point', 'Track', 'gx:Track'],
41928 // all root placemarks in the file
41929 placemarks = get(doc, 'Placemark'),
41930 styles = get(doc, 'Style'),
41931 styleMaps = get(doc, 'StyleMap');
41933 for (var k = 0; k < styles.length; k++) {
41934 var hash = okhash(xml2str(styles[k])).toString(16);
41935 styleIndex['#' + attr(styles[k], 'id')] = hash;
41936 styleByHash[hash] = styles[k];
41938 for (var l = 0; l < styleMaps.length; l++) {
41939 styleIndex['#' + attr(styleMaps[l], 'id')] = okhash(xml2str(styleMaps[l])).toString(16);
41940 var pairs = get(styleMaps[l], 'Pair');
41942 for (var m = 0; m < pairs.length; m++) {
41943 pairsMap[nodeVal(get1(pairs[m], 'key'))] = nodeVal(get1(pairs[m], 'styleUrl'));
41945 styleMapIndex['#' + attr(styleMaps[l], 'id')] = pairsMap;
41948 for (var j = 0; j < placemarks.length; j++) {
41949 gj.features = gj.features.concat(getPlacemark(placemarks[j]));
41951 function kmlColor(v) {
41952 var color, opacity;
41954 if (v.substr(0, 1) === '#') { v = v.substr(1); }
41955 if (v.length === 6 || v.length === 3) { color = v; }
41956 if (v.length === 8) {
41957 opacity = parseInt(v.substr(0, 2), 16) / 255;
41958 color = '#' + v.substr(6, 2) +
41962 return [color, isNaN(opacity) ? undefined : opacity];
41964 function gxCoord(v) { return numarray(v.split(' ')); }
41965 function gxCoords(root) {
41966 var elems = get(root, 'coord', 'gx'), coords = [], times = [];
41967 if (elems.length === 0) elems = get(root, 'gx:coord');
41968 for (var i = 0; i < elems.length; i++) coords.push(gxCoord(nodeVal(elems[i])));
41969 var timeElems = get(root, 'when');
41970 for (var j = 0; j < timeElems.length; j++) times.push(nodeVal(timeElems[j]));
41976 function getGeometry(root) {
41977 var geomNode, geomNodes, i, j, k, geoms = [], coordTimes = [];
41978 if (get1(root, 'MultiGeometry')) { return getGeometry(get1(root, 'MultiGeometry')); }
41979 if (get1(root, 'MultiTrack')) { return getGeometry(get1(root, 'MultiTrack')); }
41980 if (get1(root, 'gx:MultiTrack')) { return getGeometry(get1(root, 'gx:MultiTrack')); }
41981 for (i = 0; i < geotypes.length; i++) {
41982 geomNodes = get(root, geotypes[i]);
41984 for (j = 0; j < geomNodes.length; j++) {
41985 geomNode = geomNodes[j];
41986 if (geotypes[i] === 'Point') {
41989 coordinates: coord1(nodeVal(get1(geomNode, 'coordinates')))
41991 } else if (geotypes[i] === 'LineString') {
41993 type: 'LineString',
41994 coordinates: coord(nodeVal(get1(geomNode, 'coordinates')))
41996 } else if (geotypes[i] === 'Polygon') {
41997 var rings = get(geomNode, 'LinearRing'),
41999 for (k = 0; k < rings.length; k++) {
42000 coords.push(coord(nodeVal(get1(rings[k], 'coordinates'))));
42004 coordinates: coords
42006 } else if (geotypes[i] === 'Track' ||
42007 geotypes[i] === 'gx:Track') {
42008 var track = gxCoords(geomNode);
42010 type: 'LineString',
42011 coordinates: track.coords
42013 if (track.times.length) coordTimes.push(track.times);
42020 coordTimes: coordTimes
42023 function getPlacemark(root) {
42024 var geomsAndTimes = getGeometry(root), i, properties = {},
42025 name = nodeVal(get1(root, 'name')),
42026 styleUrl = nodeVal(get1(root, 'styleUrl')),
42027 description = nodeVal(get1(root, 'description')),
42028 timeSpan = get1(root, 'TimeSpan'),
42029 timeStamp = get1(root, 'TimeStamp'),
42030 extendedData = get1(root, 'ExtendedData'),
42031 lineStyle = get1(root, 'LineStyle'),
42032 polyStyle = get1(root, 'PolyStyle'),
42033 visibility = get1(root, 'visibility');
42035 if (!geomsAndTimes.geoms.length) return [];
42036 if (name) properties.name = name;
42038 if (styleUrl[0] !== '#') {
42039 styleUrl = '#' + styleUrl;
42042 properties.styleUrl = styleUrl;
42043 if (styleIndex[styleUrl]) {
42044 properties.styleHash = styleIndex[styleUrl];
42046 if (styleMapIndex[styleUrl]) {
42047 properties.styleMapHash = styleMapIndex[styleUrl];
42048 properties.styleHash = styleIndex[styleMapIndex[styleUrl].normal];
42050 // Try to populate the lineStyle or polyStyle since we got the style hash
42051 var style = styleByHash[properties.styleHash];
42053 if (!lineStyle) lineStyle = get1(style, 'LineStyle');
42054 if (!polyStyle) polyStyle = get1(style, 'PolyStyle');
42057 if (description) properties.description = description;
42059 var begin = nodeVal(get1(timeSpan, 'begin'));
42060 var end = nodeVal(get1(timeSpan, 'end'));
42061 properties.timespan = { begin: begin, end: end };
42064 properties.timestamp = nodeVal(get1(timeStamp, 'when'));
42067 var linestyles = kmlColor(nodeVal(get1(lineStyle, 'color'))),
42068 color = linestyles[0],
42069 opacity = linestyles[1],
42070 width = parseFloat(nodeVal(get1(lineStyle, 'width')));
42071 if (color) properties.stroke = color;
42072 if (!isNaN(opacity)) properties['stroke-opacity'] = opacity;
42073 if (!isNaN(width)) properties['stroke-width'] = width;
42076 var polystyles = kmlColor(nodeVal(get1(polyStyle, 'color'))),
42077 pcolor = polystyles[0],
42078 popacity = polystyles[1],
42079 fill = nodeVal(get1(polyStyle, 'fill')),
42080 outline = nodeVal(get1(polyStyle, 'outline'));
42081 if (pcolor) properties.fill = pcolor;
42082 if (!isNaN(popacity)) properties['fill-opacity'] = popacity;
42083 if (fill) properties['fill-opacity'] = fill === '1' ? properties['fill-opacity'] || 1 : 0;
42084 if (outline) properties['stroke-opacity'] = outline === '1' ? properties['stroke-opacity'] || 1 : 0;
42086 if (extendedData) {
42087 var datas = get(extendedData, 'Data'),
42088 simpleDatas = get(extendedData, 'SimpleData');
42090 for (i = 0; i < datas.length; i++) {
42091 properties[datas[i].getAttribute('name')] = nodeVal(get1(datas[i], 'value'));
42093 for (i = 0; i < simpleDatas.length; i++) {
42094 properties[simpleDatas[i].getAttribute('name')] = nodeVal(simpleDatas[i]);
42098 properties.visibility = nodeVal(visibility);
42100 if (geomsAndTimes.coordTimes.length) {
42101 properties.coordTimes = (geomsAndTimes.coordTimes.length === 1) ?
42102 geomsAndTimes.coordTimes[0] : geomsAndTimes.coordTimes;
42106 geometry: (geomsAndTimes.geoms.length === 1) ? geomsAndTimes.geoms[0] : {
42107 type: 'GeometryCollection',
42108 geometries: geomsAndTimes.geoms
42110 properties: properties
42112 if (attr(root, 'id')) feature.id = attr(root, 'id');
42117 gpx: function(doc) {
42119 tracks = get(doc, 'trk'),
42120 routes = get(doc, 'rte'),
42121 waypoints = get(doc, 'wpt'),
42122 // a feature collection
42125 for (i = 0; i < tracks.length; i++) {
42126 feature = getTrack(tracks[i]);
42127 if (feature) gj.features.push(feature);
42129 for (i = 0; i < routes.length; i++) {
42130 feature = getRoute(routes[i]);
42131 if (feature) gj.features.push(feature);
42133 for (i = 0; i < waypoints.length; i++) {
42134 gj.features.push(getPoint(waypoints[i]));
42136 function getPoints(node, pointname) {
42137 var pts = get(node, pointname),
42142 if (l < 2) return {}; // Invalid line in GeoJSON
42143 for (var i = 0; i < l; i++) {
42144 var c = coordPair(pts[i]);
42145 line.push(c.coordinates);
42146 if (c.time) times.push(c.time);
42147 if (c.heartRate) heartRates.push(c.heartRate);
42152 heartRates: heartRates
42155 function getTrack(node) {
42156 var segments = get(node, 'trkseg'),
42161 for (var i = 0; i < segments.length; i++) {
42162 line = getPoints(segments[i], 'trkpt');
42164 if (line.line) track.push(line.line);
42165 if (line.times && line.times.length) times.push(line.times);
42166 if (line.heartRates && line.heartRates.length) heartRates.push(line.heartRates);
42169 if (track.length === 0) return;
42170 var properties = getProperties(node);
42171 if (times.length) properties.coordTimes = track.length === 1 ? times[0] : times;
42172 if (heartRates.length) properties.heartRates = track.length === 1 ? heartRates[0] : heartRates;
42175 properties: properties,
42177 type: track.length === 1 ? 'LineString' : 'MultiLineString',
42178 coordinates: track.length === 1 ? track[0] : track
42182 function getRoute(node) {
42183 var line = getPoints(node, 'rtept');
42184 if (!line.line) return;
42187 properties: getProperties(node),
42189 type: 'LineString',
42190 coordinates: line.line
42195 function getPoint(node) {
42196 var prop = getProperties(node);
42197 extend(prop, getMulti(node, ['sym', 'type']));
42203 coordinates: coordPair(node).coordinates
42207 function getProperties(node) {
42209 prop = getMulti(node, ['name', 'cmt', 'desc', 'time', 'keywords']);
42210 links = get(node, 'link');
42211 if (links.length) prop.links = [];
42212 for (var i = 0, link; i < links.length; i++) {
42213 link = { href: attr(links[i], 'href') };
42214 extend(link, getMulti(links[i], ['text', 'type']));
42215 prop.links.push(link);
42225 if (typeof module !== 'undefined') module.exports = toGeoJSON;
42228 function svgGpx(projection, context, dispatch$$1) {
42229 var showLabels = true,
42230 detected = utilDetect(),
42235 if (svgGpx.initialized) return; // run once
42237 svgGpx.geojson = {};
42238 svgGpx.enabled = true;
42241 event.stopPropagation();
42242 event.preventDefault();
42243 event.dataTransfer.dropEffect = 'copy';
42247 .attr('dropzone', 'copy')
42248 .on('drop.localgpx', function() {
42249 event.stopPropagation();
42250 event.preventDefault();
42251 if (!detected.filedrop) return;
42252 drawGpx.files(event.dataTransfer.files);
42254 .on('dragenter.localgpx', over)
42255 .on('dragexit.localgpx', over)
42256 .on('dragover.localgpx', over);
42258 svgGpx.initialized = true;
42262 function drawGpx(selection$$1) {
42263 var geojson = svgGpx.geojson,
42264 enabled = svgGpx.enabled;
42266 layer = selection$$1.selectAll('.layer-gpx')
42267 .data(enabled ? [0] : []);
42272 layer = layer.enter()
42274 .attr('class', 'layer-gpx')
42285 paths = paths.enter()
42287 .attr('class', 'gpx')
42291 var path$$1 = index$5(projection);
42294 .attr('d', path$$1);
42297 var labels = layer.selectAll('text')
42298 .data(showLabels && geojson.features ? geojson.features : []);
42303 labels = labels.enter()
42305 .attr('class', 'gpx')
42309 .text(function(d) {
42310 return d.properties.desc || d.properties.name;
42312 .attr('x', function(d) {
42313 var centroid = path$$1.centroid(d);
42314 return centroid[0] + 7;
42316 .attr('y', function(d) {
42317 var centroid = path$$1.centroid(d);
42318 return centroid[1];
42324 function toDom(x) {
42325 return (new DOMParser()).parseFromString(x, 'text/xml');
42329 drawGpx.showLabels = function(_) {
42330 if (!arguments.length) return showLabels;
42336 drawGpx.enabled = function(_) {
42337 if (!arguments.length) return svgGpx.enabled;
42338 svgGpx.enabled = _;
42339 dispatch$$1.call('change');
42344 drawGpx.hasGpx = function() {
42345 var geojson = svgGpx.geojson;
42346 return (!(lodash.isEmpty(geojson) || lodash.isEmpty(geojson.features)));
42350 drawGpx.geojson = function(gj) {
42351 if (!arguments.length) return svgGpx.geojson;
42352 if (lodash.isEmpty(gj) || lodash.isEmpty(gj.features)) return this;
42353 svgGpx.geojson = gj;
42354 dispatch$$1.call('change');
42359 drawGpx.url = function(url) {
42360 text(url, function(err, data) {
42362 drawGpx.geojson(togeojson.gpx(toDom(data)));
42369 drawGpx.files = function(fileList) {
42370 if (!fileList.length) return this;
42371 var f = fileList[0],
42372 reader = new FileReader();
42374 reader.onload = function(e) {
42375 drawGpx.geojson(togeojson.gpx(toDom(e.target.result))).fitZoom();
42378 reader.readAsText(f);
42383 drawGpx.fitZoom = function() {
42384 if (!this.hasGpx()) return this;
42385 var geojson = svgGpx.geojson;
42387 var map$$1 = context.map(),
42388 viewport = map$$1.trimmedExtent().polygon(),
42389 coords = lodash.reduce(geojson.features, function(coords, feature) {
42390 var c = feature.geometry.coordinates;
42391 return lodash.union(coords, feature.geometry.type === 'Point' ? [c] : c);
42394 if (!geoPolygonIntersectsPolygon(viewport, coords, true)) {
42395 var extent$$1 = geoExtent$$1(bounds(geojson));
42396 map$$1.centerZoom(extent$$1.center(), map$$1.trimmedExtentZoom(extent$$1));
42407 function svgIcon(name, svgklass, useklass) {
42408 return function drawIcon(selection) {
42409 selection.selectAll('svg')
42413 .attr('class', 'icon ' + (svgklass || ''))
42415 .attr('xlink:href', name)
42416 .attr('class', useklass);
42420 function svgLabels(projection, context) {
42421 var path$$1 = index$5(projection),
42422 detected = utilDetect(),
42423 baselineHack = (detected.ie || detected.browser.toLowerCase() === 'edge'),
42424 rdrawn = index$8(),
42425 rskipped = index$8(),
42426 textWidthCache = {},
42429 // Listed from highest to lowest priority
42431 ['line', 'aeroway', '*', 12],
42432 ['line', 'highway', 'motorway', 12],
42433 ['line', 'highway', 'trunk', 12],
42434 ['line', 'highway', 'primary', 12],
42435 ['line', 'highway', 'secondary', 12],
42436 ['line', 'highway', 'tertiary', 12],
42437 ['line', 'highway', '*', 12],
42438 ['line', 'railway', '*', 12],
42439 ['line', 'waterway', '*', 12],
42440 ['area', 'aeroway', '*', 12],
42441 ['area', 'amenity', '*', 12],
42442 ['area', 'building', '*', 12],
42443 ['area', 'historic', '*', 12],
42444 ['area', 'leisure', '*', 12],
42445 ['area', 'man_made', '*', 12],
42446 ['area', 'natural', '*', 12],
42447 ['area', 'shop', '*', 12],
42448 ['area', 'tourism', '*', 12],
42449 ['area', 'camp_site', '*', 12],
42450 ['point', 'aeroway', '*', 10],
42451 ['point', 'amenity', '*', 10],
42452 ['point', 'building', '*', 10],
42453 ['point', 'historic', '*', 10],
42454 ['point', 'leisure', '*', 10],
42455 ['point', 'man_made', '*', 10],
42456 ['point', 'natural', '*', 10],
42457 ['point', 'shop', '*', 10],
42458 ['point', 'tourism', '*', 10],
42459 ['point', 'camp_site', '*', 10],
42460 ['line', 'name', '*', 12],
42461 ['area', 'name', '*', 12],
42462 ['point', 'name', '*', 10]
42466 function blacklisted(preset) {
42467 var noIcons = ['building', 'landuse', 'natural'];
42468 return lodash.some(noIcons, function(s) {
42469 return preset.id.indexOf(s) >= 0;
42474 function get(array, prop) {
42475 return function(d, i) { return array[i][prop]; };
42479 function textWidth(text$$1, size, elem) {
42480 var c = textWidthCache[size];
42481 if (!c) c = textWidthCache[size] = {};
42487 c[text$$1] = elem.getComputedTextLength();
42491 var str = encodeURIComponent(text$$1).match(/%[CDEFcdef]/g);
42492 if (str === null) {
42493 return size / 3 * 2 * text$$1.length;
42495 return size / 3 * (2 * text$$1.length + str.length);
42501 function drawLinePaths(selection$$1, entities, filter, classes, labels) {
42502 var paths = selection$$1.selectAll('path')
42504 .data(entities, osmEntity$$1.key);
42511 .style('stroke-width', get(labels, 'font-size'))
42512 .attr('id', function(d) { return 'labelpath-' + d.id; })
42513 .attr('class', classes)
42515 .attr('d', get(labels, 'lineString'));
42519 function drawLineLabels(selection$$1, entities, filter, classes, labels) {
42520 var texts = selection$$1.selectAll('text.' + classes)
42522 .data(entities, osmEntity$$1.key);
42529 .attr('class', function(d, i) { return classes + ' ' + labels[i].classes + ' ' + d.id; })
42530 .attr('dy', baselineHack ? '0.35em' : null)
42531 .append('textPath')
42532 .attr('class', 'textpath');
42534 texts = selection$$1.selectAll('text.' + classes);
42536 texts.selectAll('.textpath')
42538 .data(entities, osmEntity$$1.key)
42539 .attr('startOffset', '50%')
42540 .attr('xlink:href', function(d) { return '#labelpath-' + d.id; })
42541 .text(utilDisplayName);
42545 function drawPointLabels(selection$$1, entities, filter, classes, labels) {
42546 var texts = selection$$1.selectAll('text.' + classes)
42548 .data(entities, osmEntity$$1.key);
42553 texts = texts.enter()
42555 .attr('class', function(d, i) {
42556 return classes + ' ' + labels[i].classes + ' ' + d.id;
42561 .attr('x', get(labels, 'x'))
42562 .attr('y', get(labels, 'y'))
42563 .style('text-anchor', get(labels, 'textAnchor'))
42564 .text(utilDisplayName)
42565 .each(function(d, i) {
42566 textWidth(utilDisplayName(d), labels[i].height, this);
42571 function drawAreaLabels(selection$$1, entities, filter, classes, labels) {
42572 entities = entities.filter(hasText);
42573 labels = labels.filter(hasText);
42574 drawPointLabels(selection$$1, entities, filter, classes, labels);
42576 function hasText(d, i) {
42577 return labels[i].hasOwnProperty('x') && labels[i].hasOwnProperty('y');
42582 function drawAreaIcons(selection$$1, entities, filter, classes, labels) {
42583 var icons = selection$$1.selectAll('use')
42585 .data(entities, osmEntity$$1.key);
42590 icons = icons.enter()
42592 .attr('class', 'icon areaicon')
42593 .attr('width', '18px')
42594 .attr('height', '18px')
42598 .attr('transform', get(labels, 'transform'))
42599 .attr('xlink:href', function(d) {
42600 var icon = context.presets().match(d, context.graph()).icon;
42601 return '#' + icon + (icon === 'hairdresser' ? '-24': '-18'); // workaround: maki hairdresser-18 broken?
42606 function drawCollisionBoxes(selection$$1, rtree, which) {
42607 var showDebug = context.getDebug('collision'),
42608 classes = 'debug ' + which + ' ' +
42609 (which === 'debug-skipped' ? 'orange' : 'yellow');
42611 var debug = selection$$1.selectAll('.layer-label-debug')
42612 .data(showDebug ? [true] : []);
42617 debug = debug.enter()
42619 .attr('class', 'layer-label-debug')
42623 var gj = rtree.all().map(function(d) {
42624 return { type: 'Polygon', coordinates: [[
42633 var debugboxes = debug.selectAll('.' + which)
42639 debugboxes = debugboxes.enter()
42641 .attr('class', classes)
42642 .merge(debugboxes);
42645 .attr('d', index$5());
42650 function drawLabels(selection$$1, graph, entities, filter, dimensions, fullRedraw) {
42651 var hidePoints = !selection$$1.selectAll('.node.point').node();
42653 var labelable = [], i, j, k, entity;
42654 for (i = 0; i < labelStack.length; i++) {
42655 labelable.push([]);
42663 for (i = 0; i < entities.length; i++) {
42664 entity = entities[i];
42666 .concat(entitybboxes[entity.id] || [])
42667 .concat(entitybboxes[entity.id + 'I'] || []);
42669 for (j = 0; j < toRemove.length; j++) {
42670 rdrawn.remove(toRemove[j]);
42671 rskipped.remove(toRemove[j]);
42676 // Split entities into groups specified by labelStack
42677 for (i = 0; i < entities.length; i++) {
42678 entity = entities[i];
42679 var geometry = entity.geometry(graph);
42681 if (geometry === 'vertex')
42683 if (hidePoints && geometry === 'point')
42686 var preset = geometry === 'area' && context.presets().match(entity, graph),
42687 icon = preset && !blacklisted(preset) && preset.icon;
42689 if (!icon && !utilDisplayName(entity))
42692 for (k = 0; k < labelStack.length; k++) {
42693 var matchGeom = labelStack[k][0],
42694 matchKey = labelStack[k][1],
42695 matchVal = labelStack[k][2],
42696 hasVal = entity.tags[matchKey];
42698 if (geometry === matchGeom && hasVal && (matchVal === '*' || matchVal === hasVal)) {
42699 labelable[k].push(entity);
42717 // Try and find a valid label for labellable entities
42718 for (k = 0; k < labelable.length; k++) {
42719 var fontSize = labelStack[k][3];
42720 for (i = 0; i < labelable[k].length; i++) {
42721 entity = labelable[k][i];
42722 var name = utilDisplayName(entity),
42723 width = name && textWidth(name, fontSize),
42725 if (entity.geometry(graph) === 'point') {
42726 p = getPointLabel(entity, width, fontSize);
42727 } else if (entity.geometry(graph) === 'line') {
42728 p = getLineLabel(entity, width, fontSize);
42729 } else if (entity.geometry(graph) === 'area') {
42730 p = getAreaLabel(entity, width, fontSize);
42733 p.classes = entity.geometry(graph) + ' tag-' + labelStack[k][1];
42734 positions[entity.geometry(graph)].push(p);
42735 labelled[entity.geometry(graph)].push(entity);
42741 function getPointLabel(entity, width, height) {
42742 var pointOffsets = {
42743 ltr: [15, -12, 'start'],
42744 rtl: [-15, -12, 'end']
42747 var coord = projection(entity.loc),
42749 textDirection = detected.textDirection,
42750 offset = pointOffsets[textDirection],
42754 x: coord[0] + offset[0],
42755 y: coord[1] + offset[1],
42756 textAnchor: offset[2]
42760 if (textDirection === 'rtl') {
42762 minX: p.x - width - margin,
42763 minY: p.y - (height / 2) - margin,
42764 maxX: p.x + margin,
42765 maxY: p.y + (height / 2) + margin
42769 minX: p.x - margin,
42770 minY: p.y - (height / 2) - margin,
42771 maxX: p.x + width + margin,
42772 maxY: p.y + (height / 2) + margin
42776 if (tryInsert([bbox], entity.id, true)) {
42782 function getLineLabel(entity, width, height) {
42783 var viewport = geoExtent$$1(context.projection.clipExtent()).polygon(),
42784 nodes = lodash.map(graph.childNodes(entity), 'loc').map(projection),
42785 length = geoPathLength(nodes);
42787 if (length < width + 20) return;
42789 // % along the line to attempt to place the label
42790 var lineOffsets = [50, 45, 55, 40, 60, 35, 65, 30, 70,
42791 25, 75, 20, 80, 15, 95, 10, 90, 5, 95];
42794 for (var i = 0; i < lineOffsets.length; i++) {
42795 var offset = lineOffsets[i],
42796 middle = offset / 100 * length,
42797 start = middle - width / 2;
42799 if (start < 0 || start + width > length) continue;
42801 // generate subpath and ignore paths that are invalid or don't cross viewport.
42802 var sub = subpath(nodes, start, start + width);
42803 if (!sub || !geoPolygonIntersectsPolygon(viewport, sub, true)) {
42807 var isReverse = reverse(sub);
42809 sub = sub.reverse();
42813 boxsize = (height + 2) / 2;
42815 for (var j = 0; j < sub.length - 1; j++) {
42817 var b = sub[j + 1];
42818 var num = Math.max(1, Math.floor(geoEuclideanDistance(a, b) / boxsize / 2));
42820 for (var box = 0; box < num; box++) {
42821 var p = geoInterp(a, b, box / num);
42822 var x0 = p[0] - boxsize - margin;
42823 var y0 = p[1] - boxsize - margin;
42824 var x1 = p[0] + boxsize + margin;
42825 var y1 = p[1] + boxsize + margin;
42828 minX: Math.min(x0, x1),
42829 minY: Math.min(y0, y1),
42830 maxX: Math.max(x0, x1),
42831 maxY: Math.max(y0, y1)
42836 if (tryInsert(bboxes, entity.id, false)) {
42838 'font-size': height + 2,
42839 lineString: lineString(sub),
42840 startOffset: offset + '%'
42845 function reverse(p) {
42846 var angle = Math.atan2(p[1][1] - p[0][1], p[1][0] - p[0][0]);
42847 return !(p[0][0] < p[p.length - 1][0] && angle < Math.PI/2 && angle > -Math.PI/2);
42850 function lineString(nodes) {
42851 return 'M' + nodes.join('L');
42854 function subpath(nodes, from, to) {
42856 start, end, i0, i1;
42858 for (var i = 0; i < nodes.length - 1; i++) {
42861 var current = geoEuclideanDistance(a, b);
42863 if (!start && sofar + current >= from) {
42864 portion = (from - sofar) / current;
42866 a[0] + portion * (b[0] - a[0]),
42867 a[1] + portion * (b[1] - a[1])
42871 if (!end && sofar + current >= to) {
42872 portion = (to - sofar) / current;
42874 a[0] + portion * (b[0] - a[0]),
42875 a[1] + portion * (b[1] - a[1])
42882 var ret = nodes.slice(i0, i1);
42883 ret.unshift(start);
42890 function getAreaLabel(entity, width, height) {
42891 var centroid = path$$1.centroid(entity.asGeoJSON(graph, true)),
42892 extent$$1 = entity.extent(graph),
42893 entitywidth = projection(extent$$1[1])[0] - projection(extent$$1[0])[0];
42895 if (isNaN(centroid[0]) || entitywidth < 20) return;
42898 iconX = centroid[0] - (iconSize / 2),
42899 iconY = centroid[1] - (iconSize / 2),
42901 textOffset = iconSize + margin,
42902 p = { transform: 'translate(' + iconX + ',' + iconY + ')' };
42907 maxX: iconX + iconSize,
42908 maxY: iconY + iconSize
42912 if (tryInsert([bbox], entity.id + 'I', true)) {
42913 if (width && entitywidth >= width + 20) {
42914 var labelX = centroid[0],
42915 labelY = centroid[1] + textOffset;
42918 minX: labelX - (width / 2) - margin,
42919 minY: labelY - (height / 2) - margin,
42920 maxX: labelX + (width / 2) + margin,
42921 maxY: labelY + (height / 2) + margin
42924 // try to add label
42925 if (tryInsert([bbox], entity.id, true)) {
42928 p.textAnchor = 'middle';
42938 function tryInsert(bboxes, id, saveSkipped) {
42939 var skipped = false,
42942 for (var i = 0; i < bboxes.length; i++) {
42946 // Check that label is visible
42947 if (bbox.minX < 0 || bbox.minY < 0 || bbox.maxX > dimensions[0] || bbox.maxY > dimensions[1]) {
42951 if (rdrawn.collides(bbox)) {
42957 entitybboxes[id] = bboxes;
42961 rskipped.load(bboxes);
42964 rdrawn.load(bboxes);
42971 var label = selection$$1.selectAll('.layer-label'),
42972 halo = selection$$1.selectAll('.layer-halo');
42975 drawPointLabels(label, labelled.point, filter, 'pointlabel', positions.point);
42976 drawPointLabels(halo, labelled.point, filter, 'pointlabel-halo', positions.point);
42979 drawLinePaths(halo, labelled.line, filter, '', positions.line);
42980 drawLineLabels(label, labelled.line, filter, 'linelabel', positions.line);
42981 drawLineLabels(halo, labelled.line, filter, 'linelabel-halo', positions.line);
42984 drawAreaLabels(label, labelled.area, filter, 'arealabel', positions.area);
42985 drawAreaLabels(halo, labelled.area, filter, 'arealabel-halo', positions.area);
42986 drawAreaIcons(label, labelled.area, filter, 'arealabel-icon', positions.area);
42989 drawCollisionBoxes(label, rskipped, 'debug-skipped');
42990 drawCollisionBoxes(label, rdrawn, 'debug-drawn');
42994 function hideOnMouseover() {
42995 if (event.buttons) return;
42997 var layers = select(this)
42998 .selectAll('.layer-label, .layer-halo');
43000 layers.selectAll('.proximate')
43001 .classed('proximate', false);
43003 var mouse$$1 = context.mouse(),
43005 bbox = { minX: mouse$$1[0] - pad, minY: mouse$$1[1] - pad, maxX: mouse$$1[0] + pad, maxY: mouse$$1[1] + pad },
43006 ids = lodash.map(rdrawn.search(bbox), 'id');
43008 layers.selectAll(utilEntitySelector(ids))
43009 .classed('proximate', true);
43013 drawLabels.observe = function(selection$$1) {
43014 selection$$1.on('mousemove.hidelabels', hideOnMouseover);
43018 drawLabels.off = function(selection$$1) {
43019 selection$$1.on('mousemove.hidelabels', null);
43026 // Copies a variable number of methods from source to target.
43027 function utilRebind(target, source) {
43028 var i = 1, n = arguments.length, method;
43030 target[method = arguments[i]] = d3_rebind(target, source, source[method]);
43035 // Method is assumed to be a standard D3 getter-setter:
43036 // If passed with no arguments, gets the value.
43037 // If passed with arguments, sets the value and returns the target.
43038 function d3_rebind(target, source, method) {
43039 return function() {
43040 var value = method.apply(source, arguments);
43041 return value === source ? target : value;
43045 function refresh(selection, node) {
43046 var cr = node.getBoundingClientRect();
43047 var prop = [cr.width, cr.height];
43048 selection.property('__dimensions__', prop);
43052 function utilGetDimensions(selection, force) {
43053 if (!selection || selection.empty()) {
43056 var node = selection.node(),
43057 cached = selection.property('__dimensions__');
43058 return (!cached || force) ? refresh(selection, node) : cached;
43062 function utilSetDimensions(selection, dimensions) {
43063 if (!selection || selection.empty()) {
43066 var node = selection.node();
43067 if (dimensions === null) {
43068 refresh(selection, node);
43072 .property('__dimensions__', [dimensions[0], dimensions[1]])
43073 .attr('width', dimensions[0])
43074 .attr('height', dimensions[1]);
43077 function svgPointTransform(projection) {
43078 return function(entity) {
43079 // http://jsperf.com/short-array-join
43080 var pt = projection(entity.loc);
43081 return 'translate(' + pt[0] + ',' + pt[1] + ')';
43085 function d3geoTile() {
43086 var size = [960, 500],
43088 scaleExtent = [0, 20],
43089 translate = [size[0] / 2, size[1] / 2],
43092 function bound(_) {
43093 return Math.min(scaleExtent[1], Math.max(scaleExtent[0], _));
43097 var z = Math.max(Math.log(scale) / Math.LN2 - 8, 0),
43098 z0 = bound(Math.round(z + zoomDelta)),
43099 k = Math.pow(2, z - z0 + 8),
43100 origin = [(translate[0] - scale / 2) / k, (translate[1] - scale / 2) / k],
43102 cols = range(Math.max(0, Math.floor(-origin[0])), Math.max(0, Math.ceil(size[0] / k - origin[0]))),
43103 rows = range(Math.max(0, Math.floor(-origin[1])), Math.max(0, Math.ceil(size[1] / k - origin[1])));
43105 rows.forEach(function(y) {
43106 cols.forEach(function(x) {
43107 tiles.push([x, y, z0]);
43111 tiles.translate = origin;
43117 tile.scaleExtent = function(_) {
43118 if (!arguments.length) return scaleExtent;
43123 tile.size = function(_) {
43124 if (!arguments.length) return size;
43129 tile.scale = function(_) {
43130 if (!arguments.length) return scale;
43135 tile.translate = function(_) {
43136 if (!arguments.length) return translate;
43141 tile.zoomDelta = function(_) {
43142 if (!arguments.length) return zoomDelta;
43150 /* global Mapillary:false */
43151 var apibase = 'https://a.mapillary.com/v2/';
43152 var viewercss = 'mapillary-js/mapillary.min.css';
43153 var viewerjs = 'mapillary-js/mapillary.min.js';
43154 var trafficocss = 'traffico/stylesheets/traffico.css';
43155 var clientId = 'NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1ZWYyMmYwNjdmNDdlNmVi';
43156 var maxResults = 1000;
43158 var dispatch$2 = dispatch('loadedImages', 'loadedSigns');
43159 var mapillaryCache;
43160 var mapillaryClicks;
43161 var mapillaryImage;
43162 var mapillarySignDefs;
43163 var mapillaryViewer;
43166 function abortRequest(i) {
43171 function nearNullIsland(x, y, z) {
43173 var center = Math.pow(2, z - 1),
43174 width = Math.pow(2, z - 6),
43175 min$$1 = center - (width / 2),
43176 max$$1 = center + (width / 2) - 1;
43177 return x >= min$$1 && x <= max$$1 && y >= min$$1 && y <= max$$1;
43183 function maxPageAtZoom(z) {
43184 if (z < 15) return 2;
43185 if (z === 15) return 5;
43186 if (z === 16) return 10;
43187 if (z === 17) return 20;
43188 if (z === 18) return 40;
43189 if (z > 18) return 80;
43193 function getTiles(projection) {
43194 var s = projection.scale() * 2 * Math.PI,
43195 z = Math.max(Math.log(s) / Math.log(2) - 8, 0),
43196 ts = 256 * Math.pow(2, z - tileZoom),
43198 s / 2 - projection.translate()[0],
43199 s / 2 - projection.translate()[1]];
43202 .scaleExtent([tileZoom, tileZoom])
43204 .size(projection.clipExtent()[1])
43205 .translate(projection.translate())()
43206 .map(function(tile) {
43207 var x = tile[0] * ts - origin[0],
43208 y = tile[1] * ts - origin[1];
43211 id: tile.toString(),
43213 extent: geoExtent$$1(
43214 projection.invert([x, y + ts]),
43215 projection.invert([x + ts, y])
43222 function loadTiles(which, url, projection) {
43223 var s = projection.scale() * 2 * Math.PI,
43224 currZoom = Math.floor(Math.max(Math.log(s) / Math.log(2) - 8, 0));
43226 var tiles = getTiles(projection).filter(function(t) {
43227 return !nearNullIsland(t.xyz[0], t.xyz[1], t.xyz[2]);
43230 lodash.filter(which.inflight, function(v, k) {
43231 var wanted = lodash.find(tiles, function(tile) { return k === (tile.id + ',0'); });
43232 if (!wanted) delete which.inflight[k];
43234 }).map(abortRequest);
43236 tiles.forEach(function(tile) {
43237 loadNextTilePage(which, currZoom, url, tile);
43242 function loadNextTilePage(which, currZoom, url, tile) {
43243 var cache = mapillaryCache[which],
43244 rect = tile.extent.rectangle(),
43245 maxPages = maxPageAtZoom(currZoom),
43246 nextPage = cache.nextPage[tile.id] || 0;
43248 if (nextPage > maxPages) return;
43250 var id = tile.id + ',' + String(nextPage);
43251 if (cache.loaded[id] || cache.inflight[id]) return;
43253 cache.inflight[id] = json(url +
43258 client_id: clientId,
43263 }), function(err, data) {
43264 cache.loaded[id] = true;
43265 delete cache.inflight[id];
43266 if (err || !data.features || !data.features.length) return;
43271 for (var i = 0; i < data.features.length; i++) {
43272 feature = data.features[i];
43273 loc = feature.geometry.coordinates;
43274 d = { key: feature.properties.key, loc: loc };
43275 if (which === 'images') d.ca = feature.properties.ca;
43276 if (which === 'signs') d.signs = feature.properties.rects;
43278 features.push({minX: loc[0], minY: loc[1], maxX: loc[0], maxY: loc[1], data: d});
43281 cache.rtree.load(features);
43283 if (which === 'images') dispatch$2.call('loadedImages');
43284 if (which === 'signs') dispatch$2.call('loadedSigns');
43286 if (data.features.length === maxResults) { // more pages to load
43287 cache.nextPage[tile.id] = nextPage + 1;
43288 loadNextTilePage(which, currZoom, url, tile);
43290 cache.nextPage[tile.id] = Infinity; // no more pages to load
43297 // partition viewport into `psize` x `psize` regions
43298 function partitionViewport(psize, projection) {
43299 var dimensions = projection.clipExtent()[1];
43300 psize = psize || 16;
43301 var cols = range(0, dimensions[0], psize),
43302 rows = range(0, dimensions[1], psize),
43305 rows.forEach(function(y) {
43306 cols.forEach(function(x) {
43307 var min$$1 = [x, y + psize],
43308 max$$1 = [x + psize, y];
43310 geoExtent$$1(projection.invert(min$$1), projection.invert(max$$1)));
43318 // no more than `limit` results per partition.
43319 function searchLimited(psize, limit, projection, rtree) {
43320 limit = limit || 3;
43322 var partitions = partitionViewport(psize, projection);
43323 return lodash.flatten(lodash.compact(lodash.map(partitions, function(extent$$1) {
43324 return rtree.search(extent$$1.bbox())
43326 .map(function(d) { return d.data; });
43332 var serviceMapillary = {
43335 if (!mapillaryCache) {
43339 this.event = utilRebind(this, dispatch$2, 'on');
43342 reset: function() {
43343 var cache = mapillaryCache;
43346 if (cache.images && cache.images.inflight) {
43347 lodash.forEach(cache.images.inflight, abortRequest);
43349 if (cache.signs && cache.signs.inflight) {
43350 lodash.forEach(cache.signs.inflight, abortRequest);
43355 images: { inflight: {}, loaded: {}, nextPage: {}, rtree: index$8() },
43356 signs: { inflight: {}, loaded: {}, nextPage: {}, rtree: index$8() }
43359 mapillaryImage = null;
43360 mapillaryClicks = [];
43364 images: function(projection) {
43365 var psize = 16, limit = 3;
43366 return searchLimited(psize, limit, projection, mapillaryCache.images.rtree);
43370 signs: function(projection) {
43371 var psize = 32, limit = 3;
43372 return searchLimited(psize, limit, projection, mapillaryCache.signs.rtree);
43376 signsSupported: function() {
43377 var detected = utilDetect();
43378 if (detected.ie) return false;
43379 if ((detected.browser.toLowerCase() === 'safari') && (parseFloat(detected.version) < 10)) return false;
43384 signHTML: function(d) {
43385 if (!mapillarySignDefs) return;
43387 var detectionPackage = d.signs[0].package,
43388 type = d.signs[0].type,
43389 country = detectionPackage.split('_')[1];
43391 return mapillarySignDefs[country][type];
43395 loadImages: function(projection) {
43396 var url = apibase + 'search/im/geojson?';
43397 loadTiles('images', url, projection);
43401 loadSigns: function(context, projection) {
43402 var url = apibase + 'search/im/geojson/or?';
43403 loadTiles('signs', url, projection);
43405 // load traffico css
43406 select('head').selectAll('#traffico')
43410 .attr('id', 'traffico')
43411 .attr('rel', 'stylesheet')
43412 .attr('href', context.asset(trafficocss));
43414 // load traffico sign defs
43415 if (!mapillarySignDefs) {
43416 mapillarySignDefs = {};
43417 lodash.each(['au', 'br', 'ca', 'de', 'us'], function(region) {
43418 json(context.asset('traffico/string-maps/' + region + '-map.json'), function(err, data) {
43420 if (region === 'de') region = 'eu';
43421 mapillarySignDefs[region] = data;
43428 loadViewer: function(context) {
43430 var wrap = select('#content').selectAll('.mapillary-wrap')
43433 var enter = wrap.enter()
43435 .attr('class', 'mapillary-wrap')
43436 .classed('al', true) // 'al'=left, 'ar'=right
43437 .classed('hidden', true);
43441 .attr('class', 'thumb-hide')
43442 .on('click', function () { that.hideViewer(); })
43444 .call(svgIcon('#icon-close'));
43449 .attr('class', 'mly-wrapper')
43450 .classed('active', false);
43452 // load mapillary-viewercss
43453 select('head').selectAll('#mapillary-viewercss')
43457 .attr('id', 'mapillary-viewercss')
43458 .attr('rel', 'stylesheet')
43459 .attr('href', context.asset(viewercss));
43461 // load mapillary-viewerjs
43462 select('head').selectAll('#mapillary-viewerjs')
43466 .attr('id', 'mapillary-viewerjs')
43467 .attr('src', context.asset(viewerjs));
43471 showViewer: function() {
43473 .selectAll('.mapillary-wrap')
43474 .classed('hidden', false)
43475 .selectAll('.mly-wrapper')
43476 .classed('active', true);
43482 hideViewer: function() {
43484 .selectAll('.mapillary-wrap')
43485 .classed('hidden', true)
43486 .selectAll('.mly-wrapper')
43487 .classed('active', false);
43489 selectAll('.layer-mapillary-images .viewfield-group, .layer-mapillary-signs .icon-sign')
43490 .classed('selected', false);
43492 mapillaryImage = null;
43497 updateViewer: function(imageKey, context) {
43498 if (!imageKey) return;
43500 if (!mapillaryViewer) {
43501 this.initViewer(imageKey, context);
43503 mapillaryViewer.moveToKey(imageKey);
43510 initViewer: function(imageKey, context) {
43512 if (Mapillary && imageKey) {
43514 baseImageSize: 320,
43521 mapillaryViewer = new Mapillary.Viewer('mly', clientId, imageKey, opts);
43522 mapillaryViewer.on('nodechanged', nodeChanged);
43525 function nodeChanged(node) {
43526 var clicks = mapillaryClicks;
43527 var index = clicks.indexOf(node.key);
43528 if (index > -1) { // nodechange initiated from clicking on a marker..
43529 clicks.splice(index, 1);
43530 } else { // nodechange initiated from the Mapillary viewer controls..
43531 var loc = node.computedLatLon ? [node.computedLatLon.lon, node.computedLatLon.lat] : [node.latLon.lon, node.latLon.lat];
43532 context.map().centerEase(loc);
43533 that.selectedImage(node.key, false);
43539 selectedImage: function(imageKey, fromClick) {
43540 if (!arguments.length) return mapillaryImage;
43542 mapillaryImage = imageKey;
43544 mapillaryClicks.push(imageKey);
43547 selectAll('.layer-mapillary-images .viewfield-group, .layer-mapillary-signs .icon-sign')
43548 .classed('selected', function(d) { return d.key === imageKey; });
43554 cache: function(_) {
43555 if (!arguments.length) return mapillaryCache;
43556 mapillaryCache = _;
43561 signDefs: function(_) {
43562 if (!arguments.length) return mapillarySignDefs;
43563 mapillarySignDefs = _;
43569 var endpoint = 'https://nominatim.openstreetmap.org/reverse?';
43570 var nominatimCache;
43573 var serviceNominatim = {
43575 init: function() { nominatimCache = index$8(); },
43576 reset: function() { nominatimCache = index$8(); },
43579 countryCode: function (location, callback) {
43580 var countryCodes = nominatimCache.search(
43581 { minX: location[0], minY: location[1], maxX: location[0], maxY: location[1] }
43584 if (countryCodes.length > 0) {
43585 return callback(null, countryCodes[0].data);
43594 }), function(err, result) {
43596 return callback(err);
43597 else if (result && result.error)
43598 return callback(result.error);
43600 var extent$$1 = geoExtent$$1(location).padByMeters(1000);
43601 nominatimCache.insert(Object.assign(extent$$1.bbox(),
43602 { data: result.address.country_code }
43605 callback(null, result.address.country_code);
43612 var hashes$1 = createCommonjsModule(function (module, exports) {
43614 * jshashes - https://github.com/h2non/jshashes
43615 * Released under the "New BSD" license
43617 * Algorithms specification:
43619 * MD5 - http://www.ietf.org/rfc/rfc1321.txt
43620 * RIPEMD-160 - http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
43621 * SHA1 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
43622 * SHA256 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
43623 * SHA512 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
43624 * HMAC - http://www.ietf.org/rfc/rfc2104.txt
43629 function utf8Encode(str) {
43630 var x, y, output = '',
43634 if (str && str.length) {
43636 while ((i += 1) < l) {
43637 /* Decode utf-16 surrogate pairs */
43638 x = str.charCodeAt(i);
43639 y = i + 1 < l ? str.charCodeAt(i + 1) : 0;
43640 if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) {
43641 x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
43644 /* Encode output as utf-8 */
43646 output += String.fromCharCode(x);
43647 } else if (x <= 0x7FF) {
43648 output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F),
43649 0x80 | (x & 0x3F));
43650 } else if (x <= 0xFFFF) {
43651 output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
43652 0x80 | ((x >>> 6) & 0x3F),
43653 0x80 | (x & 0x3F));
43654 } else if (x <= 0x1FFFFF) {
43655 output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
43656 0x80 | ((x >>> 12) & 0x3F),
43657 0x80 | ((x >>> 6) & 0x3F),
43658 0x80 | (x & 0x3F));
43665 function utf8Decode(str) {
43666 var i, ac, c1, c2, c3, arr = [],
43668 i = ac = c1 = c2 = c3 = 0;
43670 if (str && str.length) {
43675 c1 = str.charCodeAt(i);
43678 arr[ac] = String.fromCharCode(c1);
43680 } else if (c1 > 191 && c1 < 224) {
43681 c2 = str.charCodeAt(i + 1);
43682 arr[ac] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
43685 c2 = str.charCodeAt(i + 1);
43686 c3 = str.charCodeAt(i + 2);
43687 arr[ac] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
43692 return arr.join('');
43696 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
43697 * to work around bugs in some JS interpreters.
43700 function safe_add(x, y) {
43701 var lsw = (x & 0xFFFF) + (y & 0xFFFF),
43702 msw = (x >> 16) + (y >> 16) + (lsw >> 16);
43703 return (msw << 16) | (lsw & 0xFFFF);
43707 * Bitwise rotate a 32-bit number to the left.
43710 function bit_rol(num, cnt) {
43711 return (num << cnt) | (num >>> (32 - cnt));
43715 * Convert a raw string to a hex string
43718 function rstr2hex(input, hexcase) {
43719 var hex_tab = hexcase ? '0123456789ABCDEF' : '0123456789abcdef',
43723 for (; i < l; i += 1) {
43724 x = input.charCodeAt(i);
43725 output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt(x & 0x0F);
43731 * Encode a string as utf-16
43734 function str2rstr_utf16le(input) {
43735 var i, l = input.length,
43737 for (i = 0; i < l; i += 1) {
43738 output += String.fromCharCode(input.charCodeAt(i) & 0xFF, (input.charCodeAt(i) >>> 8) & 0xFF);
43743 function str2rstr_utf16be(input) {
43744 var i, l = input.length,
43746 for (i = 0; i < l; i += 1) {
43747 output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, input.charCodeAt(i) & 0xFF);
43753 * Convert an array of big-endian words to a string
43756 function binb2rstr(input) {
43757 var i, l = input.length * 32,
43759 for (i = 0; i < l; i += 8) {
43760 output += String.fromCharCode((input[i >> 5] >>> (24 - i % 32)) & 0xFF);
43766 * Convert an array of little-endian words to a string
43769 function binl2rstr(input) {
43770 var i, l = input.length * 32,
43772 for (i = 0; i < l; i += 8) {
43773 output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
43779 * Convert a raw string to an array of little-endian words
43780 * Characters >255 have their high-byte silently ignored.
43783 function rstr2binl(input) {
43784 var i, l = input.length * 8,
43785 output = Array(input.length >> 2),
43786 lo = output.length;
43787 for (i = 0; i < lo; i += 1) {
43790 for (i = 0; i < l; i += 8) {
43791 output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);
43797 * Convert a raw string to an array of big-endian words
43798 * Characters >255 have their high-byte silently ignored.
43801 function rstr2binb(input) {
43802 var i, l = input.length * 8,
43803 output = Array(input.length >> 2),
43804 lo = output.length;
43805 for (i = 0; i < lo; i += 1) {
43808 for (i = 0; i < l; i += 8) {
43809 output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
43815 * Convert a raw string to an arbitrary string encoding
43818 function rstr2any(input, encoding) {
43819 var divisor = encoding.length,
43820 remainders = Array(),
43821 i, q, x, ld, quotient, dividend, output, full_length;
43823 /* Convert to an array of 16-bit big-endian values, forming the dividend */
43824 dividend = Array(Math.ceil(input.length / 2));
43825 ld = dividend.length;
43826 for (i = 0; i < ld; i += 1) {
43827 dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
43831 * Repeatedly perform a long division. The binary array forms the dividend,
43832 * the length of the encoding is the divisor. Once computed, the quotient
43833 * forms the dividend for the next step. We stop when the dividend is zerHashes.
43834 * All remainders are stored for later use.
43836 while (dividend.length > 0) {
43837 quotient = Array();
43839 for (i = 0; i < dividend.length; i += 1) {
43840 x = (x << 16) + dividend[i];
43841 q = Math.floor(x / divisor);
43843 if (quotient.length > 0 || q > 0) {
43844 quotient[quotient.length] = q;
43847 remainders[remainders.length] = x;
43848 dividend = quotient;
43851 /* Convert the remainders to the output string */
43853 for (i = remainders.length - 1; i >= 0; i--) {
43854 output += encoding.charAt(remainders[i]);
43857 /* Append leading zero equivalents */
43858 full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2)));
43859 for (i = output.length; i < full_length; i += 1) {
43860 output = encoding[0] + output;
43866 * Convert a raw string to a base-64 string
43869 function rstr2b64(input, b64pad) {
43870 var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
43872 len = input.length,
43874 b64pad = b64pad || '=';
43875 for (i = 0; i < len; i += 3) {
43876 triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0);
43877 for (j = 0; j < 4; j += 1) {
43878 if (i * 8 + j * 6 > input.length * 8) {
43881 output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F);
43890 * @property {String} version
43899 Base64: function() {
43900 // private properties
43901 var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
43902 pad = '=', // default pad according with the RFC standard
43903 url = false, // URL encoding support @todo
43904 utf8 = true; // by default enable UTF-8 support encoding
43906 // public method for encoding
43907 this.encode = function(input) {
43910 len = input.length;
43913 input = (utf8) ? utf8Encode(input) : input;
43915 for (i = 0; i < len; i += 3) {
43916 triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0);
43917 for (j = 0; j < 4; j += 1) {
43918 if (i * 8 + j * 6 > len * 8) {
43921 output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F);
43928 // public method for decoding
43929 this.decode = function(input) {
43930 // var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
43931 var i, o1, o2, o3, h1, h2, h3, h4, bits, ac,
43939 input = input.replace(new RegExp('\\' + pad, 'gi'), ''); // use '='
43942 do { // unpack four hexets into three octets using index points in b64
43943 h1 = tab.indexOf(input.charAt(i += 1));
43944 h2 = tab.indexOf(input.charAt(i += 1));
43945 h3 = tab.indexOf(input.charAt(i += 1));
43946 h4 = tab.indexOf(input.charAt(i += 1));
43948 bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
43950 o1 = bits >> 16 & 0xff;
43951 o2 = bits >> 8 & 0xff;
43956 arr[ac] = String.fromCharCode(o1);
43957 } else if (h4 === 64) {
43958 arr[ac] = String.fromCharCode(o1, o2);
43960 arr[ac] = String.fromCharCode(o1, o2, o3);
43962 } while (i < input.length);
43964 dec = arr.join('');
43965 dec = (utf8) ? utf8Decode(dec) : dec;
43970 // set custom pad string
43971 this.setPad = function(str) {
43975 // set custom tab string characters
43976 this.setTab = function(str) {
43980 this.setUTF8 = function(bool) {
43981 if (typeof bool === 'boolean') {
43989 * CRC-32 calculation
43993 * @param {String} str Input String
43996 CRC32: function(str) {
44001 str = utf8Encode(str);
44004 '00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 ',
44005 '79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 ',
44006 '84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F ',
44007 '63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD ',
44008 'A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC ',
44009 '51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 ',
44010 'B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 ',
44011 '06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 ',
44012 'E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 ',
44013 '12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 ',
44014 'D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 ',
44015 '33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 ',
44016 'CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 ',
44017 '9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E ',
44018 '7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D ',
44019 '806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 ',
44020 '60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA ',
44021 'AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 ',
44022 '5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 ',
44023 'B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 ',
44024 '05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 ',
44025 'F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA ',
44026 '11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 ',
44027 'D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F ',
44028 '30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E ',
44029 'C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D'
44033 for (i = 0, iTop = str.length; i < iTop; i += 1) {
44034 y = (crc ^ str.charCodeAt(i)) & 0xFF;
44035 x = '0x' + table.substr(y * 9, 8);
44036 crc = (crc >>> 8) ^ x;
44038 // always return a positive number (that's what >>> 0 does)
44039 return (crc ^ (-1)) >>> 0;
44045 * @param {Object} [config]
44047 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
44048 * Digest Algorithm, as defined in RFC 1321.
44049 * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
44050 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
44051 * See <http://pajhome.org.uk/crypt/md5> for more infHashes.
44053 MD5: function(options) {
44055 * Private config properties. You may need to tweak these to be compatible with
44056 * the server-side, but the defaults work in most cases.
44057 * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase}
44059 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase
44060 b64pad = (options && typeof options.pad === 'string') ? options.pda : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance
44061 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding
44063 // privileged (public) methods
44064 this.hex = function(s) {
44065 return rstr2hex(rstr(s, utf8), hexcase);
44067 this.b64 = function(s) {
44068 return rstr2b64(rstr(s), b64pad);
44070 this.any = function(s, e) {
44071 return rstr2any(rstr(s, utf8), e);
44073 this.raw = function(s) {
44074 return rstr(s, utf8);
44076 this.hex_hmac = function(k, d) {
44077 return rstr2hex(rstr_hmac(k, d), hexcase);
44079 this.b64_hmac = function(k, d) {
44080 return rstr2b64(rstr_hmac(k, d), b64pad);
44082 this.any_hmac = function(k, d, e) {
44083 return rstr2any(rstr_hmac(k, d), e);
44086 * Perform a simple self-test to see if the VM is working
44087 * @return {String} Hexadecimal hash sample
44089 this.vm_test = function() {
44090 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
44093 * Enable/disable uppercase hexadecimal returned string
44095 * @return {Object} this
44097 this.setUpperCase = function(a) {
44098 if (typeof a === 'boolean') {
44104 * Defines a base64 pad string
44105 * @param {String} Pad
44106 * @return {Object} this
44108 this.setPad = function(a) {
44109 b64pad = a || b64pad;
44113 * Defines a base64 pad string
44115 * @return {Object} [this]
44117 this.setUTF8 = function(a) {
44118 if (typeof a === 'boolean') {
44127 * Calculate the MD5 of a raw string
44131 s = (utf8) ? utf8Encode(s) : s;
44132 return binl2rstr(binl(rstr2binl(s), s.length * 8));
44136 * Calculate the HMAC-MD5, of a key and some data (raw strings)
44139 function rstr_hmac(key, data) {
44140 var bkey, ipad, opad, hash, i;
44142 key = (utf8) ? utf8Encode(key) : key;
44143 data = (utf8) ? utf8Encode(data) : data;
44144 bkey = rstr2binl(key);
44145 if (bkey.length > 16) {
44146 bkey = binl(bkey, key.length * 8);
44149 ipad = Array(16), opad = Array(16);
44150 for (i = 0; i < 16; i += 1) {
44151 ipad[i] = bkey[i] ^ 0x36363636;
44152 opad[i] = bkey[i] ^ 0x5C5C5C5C;
44154 hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
44155 return binl2rstr(binl(opad.concat(hash), 512 + 128));
44159 * Calculate the MD5 of an array of little-endian words, and a bit length.
44162 function binl(x, len) {
44163 var i, olda, oldb, oldc, oldd,
44169 /* append padding */
44170 x[len >> 5] |= 0x80 << ((len) % 32);
44171 x[(((len + 64) >>> 9) << 4) + 14] = len;
44173 for (i = 0; i < x.length; i += 16) {
44179 a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
44180 d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
44181 c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
44182 b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
44183 a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
44184 d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
44185 c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
44186 b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
44187 a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
44188 d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
44189 c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
44190 b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
44191 a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
44192 d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
44193 c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
44194 b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
44196 a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
44197 d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
44198 c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
44199 b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
44200 a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
44201 d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
44202 c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
44203 b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
44204 a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
44205 d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
44206 c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
44207 b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
44208 a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
44209 d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
44210 c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
44211 b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
44213 a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
44214 d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
44215 c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
44216 b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
44217 a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
44218 d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
44219 c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
44220 b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
44221 a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
44222 d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
44223 c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
44224 b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
44225 a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
44226 d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
44227 c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
44228 b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
44230 a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
44231 d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
44232 c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
44233 b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
44234 a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
44235 d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
44236 c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
44237 b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
44238 a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
44239 d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
44240 c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
44241 b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
44242 a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
44243 d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
44244 c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
44245 b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
44247 a = safe_add(a, olda);
44248 b = safe_add(b, oldb);
44249 c = safe_add(c, oldc);
44250 d = safe_add(d, oldd);
44252 return Array(a, b, c, d);
44256 * These functions implement the four basic operations the algorithm uses.
44259 function md5_cmn(q, a, b, x, s, t) {
44260 return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
44263 function md5_ff(a, b, c, d, x, s, t) {
44264 return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
44267 function md5_gg(a, b, c, d, x, s, t) {
44268 return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
44271 function md5_hh(a, b, c, d, x, s, t) {
44272 return md5_cmn(b ^ c ^ d, a, b, x, s, t);
44275 function md5_ii(a, b, c, d, x, s, t) {
44276 return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
44281 * @class Hashes.SHA1
44282 * @param {Object} [config]
44285 * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined in FIPS 180-1
44286 * Version 2.2 Copyright Paul Johnston 2000 - 2009.
44287 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
44288 * See http://pajhome.org.uk/crypt/md5 for details.
44290 SHA1: function(options) {
44292 * Private config properties. You may need to tweak these to be compatible with
44293 * the server-side, but the defaults work in most cases.
44294 * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase}
44296 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase
44297 b64pad = (options && typeof options.pad === 'string') ? options.pda : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance
44298 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding
44301 this.hex = function(s) {
44302 return rstr2hex(rstr(s, utf8), hexcase);
44304 this.b64 = function(s) {
44305 return rstr2b64(rstr(s, utf8), b64pad);
44307 this.any = function(s, e) {
44308 return rstr2any(rstr(s, utf8), e);
44310 this.raw = function(s) {
44311 return rstr(s, utf8);
44313 this.hex_hmac = function(k, d) {
44314 return rstr2hex(rstr_hmac(k, d));
44316 this.b64_hmac = function(k, d) {
44317 return rstr2b64(rstr_hmac(k, d), b64pad);
44319 this.any_hmac = function(k, d, e) {
44320 return rstr2any(rstr_hmac(k, d), e);
44323 * Perform a simple self-test to see if the VM is working
44324 * @return {String} Hexadecimal hash sample
44327 this.vm_test = function() {
44328 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
44331 * @description Enable/disable uppercase hexadecimal returned string
44333 * @return {Object} this
44336 this.setUpperCase = function(a) {
44337 if (typeof a === 'boolean') {
44343 * @description Defines a base64 pad string
44344 * @param {string} Pad
44345 * @return {Object} this
44348 this.setPad = function(a) {
44349 b64pad = a || b64pad;
44353 * @description Defines a base64 pad string
44355 * @return {Object} this
44358 this.setUTF8 = function(a) {
44359 if (typeof a === 'boolean') {
44368 * Calculate the SHA-512 of a raw string
44372 s = (utf8) ? utf8Encode(s) : s;
44373 return binb2rstr(binb(rstr2binb(s), s.length * 8));
44377 * Calculate the HMAC-SHA1 of a key and some data (raw strings)
44380 function rstr_hmac(key, data) {
44381 var bkey, ipad, opad, i, hash;
44382 key = (utf8) ? utf8Encode(key) : key;
44383 data = (utf8) ? utf8Encode(data) : data;
44384 bkey = rstr2binb(key);
44386 if (bkey.length > 16) {
44387 bkey = binb(bkey, key.length * 8);
44389 ipad = Array(16), opad = Array(16);
44390 for (i = 0; i < 16; i += 1) {
44391 ipad[i] = bkey[i] ^ 0x36363636;
44392 opad[i] = bkey[i] ^ 0x5C5C5C5C;
44394 hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
44395 return binb2rstr(binb(opad.concat(hash), 512 + 160));
44399 * Calculate the SHA-1 of an array of big-endian words, and a bit length
44402 function binb(x, len) {
44403 var i, j, t, olda, oldb, oldc, oldd, olde,
44411 /* append padding */
44412 x[len >> 5] |= 0x80 << (24 - len % 32);
44413 x[((len + 64 >> 9) << 4) + 15] = len;
44415 for (i = 0; i < x.length; i += 16) {
44422 for (j = 0; j < 80; j += 1) {
44426 w[j] = bit_rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
44428 t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
44429 safe_add(safe_add(e, w[j]), sha1_kt(j)));
44432 c = bit_rol(b, 30);
44437 a = safe_add(a, olda);
44438 b = safe_add(b, oldb);
44439 c = safe_add(c, oldc);
44440 d = safe_add(d, oldd);
44441 e = safe_add(e, olde);
44443 return Array(a, b, c, d, e);
44447 * Perform the appropriate triplet combination function for the current
44451 function sha1_ft(t, b, c, d) {
44453 return (b & c) | ((~b) & d);
44459 return (b & c) | (b & d) | (c & d);
44465 * Determine the appropriate additive constant for the current iteration
44468 function sha1_kt(t) {
44469 return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
44470 (t < 60) ? -1894007588 : -899497514;
44474 * @class Hashes.SHA256
44477 * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined in FIPS 180-2
44478 * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009.
44479 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
44480 * See http://pajhome.org.uk/crypt/md5 for details.
44481 * Also http://anmar.eu.org/projects/jssha2/
44483 SHA256: function(options) {
44485 * Private properties configuration variables. You may need to tweak these to be compatible with
44486 * the server-side, but the defaults work in most cases.
44487 * @see this.setUpperCase() method
44488 * @see this.setPad() method
44490 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase */
44491 b64pad = (options && typeof options.pad === 'string') ? options.pda : '=',
44492 /* base-64 pad character. Default '=' for strict RFC compliance */
44493 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
44494 /* enable/disable utf8 encoding */
44497 /* privileged (public) methods */
44498 this.hex = function(s) {
44499 return rstr2hex(rstr(s, utf8));
44501 this.b64 = function(s) {
44502 return rstr2b64(rstr(s, utf8), b64pad);
44504 this.any = function(s, e) {
44505 return rstr2any(rstr(s, utf8), e);
44507 this.raw = function(s) {
44508 return rstr(s, utf8);
44510 this.hex_hmac = function(k, d) {
44511 return rstr2hex(rstr_hmac(k, d));
44513 this.b64_hmac = function(k, d) {
44514 return rstr2b64(rstr_hmac(k, d), b64pad);
44516 this.any_hmac = function(k, d, e) {
44517 return rstr2any(rstr_hmac(k, d), e);
44520 * Perform a simple self-test to see if the VM is working
44521 * @return {String} Hexadecimal hash sample
44524 this.vm_test = function() {
44525 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
44528 * Enable/disable uppercase hexadecimal returned string
44530 * @return {Object} this
44533 this.setUpperCase = function(a) {
44534 if (typeof a === 'boolean') {
44540 * @description Defines a base64 pad string
44541 * @param {string} Pad
44542 * @return {Object} this
44545 this.setPad = function(a) {
44546 b64pad = a || b64pad;
44550 * Defines a base64 pad string
44552 * @return {Object} this
44555 this.setUTF8 = function(a) {
44556 if (typeof a === 'boolean') {
44565 * Calculate the SHA-512 of a raw string
44568 function rstr(s, utf8) {
44569 s = (utf8) ? utf8Encode(s) : s;
44570 return binb2rstr(binb(rstr2binb(s), s.length * 8));
44574 * Calculate the HMAC-sha256 of a key and some data (raw strings)
44577 function rstr_hmac(key, data) {
44578 key = (utf8) ? utf8Encode(key) : key;
44579 data = (utf8) ? utf8Encode(data) : data;
44581 bkey = rstr2binb(key),
44585 if (bkey.length > 16) {
44586 bkey = binb(bkey, key.length * 8);
44589 for (; i < 16; i += 1) {
44590 ipad[i] = bkey[i] ^ 0x36363636;
44591 opad[i] = bkey[i] ^ 0x5C5C5C5C;
44594 hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
44595 return binb2rstr(binb(opad.concat(hash), 512 + 256));
44599 * Main sha256 function, with its support functions
44602 function sha256_S(X, n) {
44603 return (X >>> n) | (X << (32 - n));
44606 function sha256_R(X, n) {
44610 function sha256_Ch(x, y, z) {
44611 return ((x & y) ^ ((~x) & z));
44614 function sha256_Maj(x, y, z) {
44615 return ((x & y) ^ (x & z) ^ (y & z));
44618 function sha256_Sigma0256(x) {
44619 return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));
44622 function sha256_Sigma1256(x) {
44623 return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));
44626 function sha256_Gamma0256(x) {
44627 return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));
44630 function sha256_Gamma1256(x) {
44631 return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));
44634 function sha256_Sigma0512(x) {
44635 return (sha256_S(x, 28) ^ sha256_S(x, 34) ^ sha256_S(x, 39));
44638 function sha256_Sigma1512(x) {
44639 return (sha256_S(x, 14) ^ sha256_S(x, 18) ^ sha256_S(x, 41));
44642 function sha256_Gamma0512(x) {
44643 return (sha256_S(x, 1) ^ sha256_S(x, 8) ^ sha256_R(x, 7));
44646 function sha256_Gamma1512(x) {
44647 return (sha256_S(x, 19) ^ sha256_S(x, 61) ^ sha256_R(x, 6));
44651 1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993, -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987,
44652 1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522,
44653 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585,
44654 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291,
44655 1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885, -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344,
44656 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218,
44657 1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872, -1866530822, -1538233109, -1090935817, -965641998
44660 function binb(m, l) {
44661 var HASH = [1779033703, -1150833019, 1013904242, -1521486534,
44662 1359893119, -1694144372, 528734635, 1541459225
44664 var W = new Array(64);
44665 var a, b, c, d, e, f, g, h;
44668 /* append padding */
44669 m[l >> 5] |= 0x80 << (24 - l % 32);
44670 m[((l + 64 >> 9) << 4) + 15] = l;
44672 for (i = 0; i < m.length; i += 16) {
44682 for (j = 0; j < 64; j += 1) {
44686 W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]),
44687 sha256_Gamma0256(W[j - 15])), W[j - 16]);
44690 T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)),
44691 sha256_K[j]), W[j]);
44692 T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c));
44696 e = safe_add(d, T1);
44700 a = safe_add(T1, T2);
44703 HASH[0] = safe_add(a, HASH[0]);
44704 HASH[1] = safe_add(b, HASH[1]);
44705 HASH[2] = safe_add(c, HASH[2]);
44706 HASH[3] = safe_add(d, HASH[3]);
44707 HASH[4] = safe_add(e, HASH[4]);
44708 HASH[5] = safe_add(f, HASH[5]);
44709 HASH[6] = safe_add(g, HASH[6]);
44710 HASH[7] = safe_add(h, HASH[7]);
44718 * @class Hashes.SHA512
44721 * A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined in FIPS 180-2
44722 * Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009.
44723 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
44724 * See http://pajhome.org.uk/crypt/md5 for details.
44726 SHA512: function(options) {
44728 * Private properties configuration variables. You may need to tweak these to be compatible with
44729 * the server-side, but the defaults work in most cases.
44730 * @see this.setUpperCase() method
44731 * @see this.setPad() method
44733 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false,
44734 /* hexadecimal output case format. false - lowercase; true - uppercase */
44735 b64pad = (options && typeof options.pad === 'string') ? options.pda : '=',
44736 /* base-64 pad character. Default '=' for strict RFC compliance */
44737 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
44738 /* enable/disable utf8 encoding */
44741 /* privileged (public) methods */
44742 this.hex = function(s) {
44743 return rstr2hex(rstr(s));
44745 this.b64 = function(s) {
44746 return rstr2b64(rstr(s), b64pad);
44748 this.any = function(s, e) {
44749 return rstr2any(rstr(s), e);
44751 this.raw = function(s) {
44752 return rstr(s, utf8);
44754 this.hex_hmac = function(k, d) {
44755 return rstr2hex(rstr_hmac(k, d));
44757 this.b64_hmac = function(k, d) {
44758 return rstr2b64(rstr_hmac(k, d), b64pad);
44760 this.any_hmac = function(k, d, e) {
44761 return rstr2any(rstr_hmac(k, d), e);
44764 * Perform a simple self-test to see if the VM is working
44765 * @return {String} Hexadecimal hash sample
44768 this.vm_test = function() {
44769 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
44772 * @description Enable/disable uppercase hexadecimal returned string
44774 * @return {Object} this
44777 this.setUpperCase = function(a) {
44778 if (typeof a === 'boolean') {
44784 * @description Defines a base64 pad string
44785 * @param {string} Pad
44786 * @return {Object} this
44789 this.setPad = function(a) {
44790 b64pad = a || b64pad;
44794 * @description Defines a base64 pad string
44796 * @return {Object} this
44799 this.setUTF8 = function(a) {
44800 if (typeof a === 'boolean') {
44806 /* private methods */
44809 * Calculate the SHA-512 of a raw string
44813 s = (utf8) ? utf8Encode(s) : s;
44814 return binb2rstr(binb(rstr2binb(s), s.length * 8));
44817 * Calculate the HMAC-SHA-512 of a key and some data (raw strings)
44820 function rstr_hmac(key, data) {
44821 key = (utf8) ? utf8Encode(key) : key;
44822 data = (utf8) ? utf8Encode(data) : data;
44825 bkey = rstr2binb(key),
44829 if (bkey.length > 32) {
44830 bkey = binb(bkey, key.length * 8);
44833 for (; i < 32; i += 1) {
44834 ipad[i] = bkey[i] ^ 0x36363636;
44835 opad[i] = bkey[i] ^ 0x5C5C5C5C;
44838 hash = binb(ipad.concat(rstr2binb(data)), 1024 + data.length * 8);
44839 return binb2rstr(binb(opad.concat(hash), 1024 + 512));
44843 * Calculate the SHA-512 of an array of big-endian dwords, and a bit length
44846 function binb(x, len) {
44849 hash = new Array(16),
44850 //Initial hash values
44852 new int64(0x6a09e667, -205731576),
44853 new int64(-1150833019, -2067093701),
44854 new int64(0x3c6ef372, -23791573),
44855 new int64(-1521486534, 0x5f1d36f1),
44856 new int64(0x510e527f, -1377402159),
44857 new int64(-1694144372, 0x2b3e6c1f),
44858 new int64(0x1f83d9ab, -79577749),
44859 new int64(0x5be0cd19, 0x137e2179)
44861 T1 = new int64(0, 0),
44862 T2 = new int64(0, 0),
44863 a = new int64(0, 0),
44864 b = new int64(0, 0),
44865 c = new int64(0, 0),
44866 d = new int64(0, 0),
44867 e = new int64(0, 0),
44868 f = new int64(0, 0),
44869 g = new int64(0, 0),
44870 h = new int64(0, 0),
44871 //Temporary variables not specified by the document
44872 s0 = new int64(0, 0),
44873 s1 = new int64(0, 0),
44874 Ch = new int64(0, 0),
44875 Maj = new int64(0, 0),
44876 r1 = new int64(0, 0),
44877 r2 = new int64(0, 0),
44878 r3 = new int64(0, 0);
44880 if (sha512_k === undefined) {
44883 new int64(0x428a2f98, -685199838), new int64(0x71374491, 0x23ef65cd),
44884 new int64(-1245643825, -330482897), new int64(-373957723, -2121671748),
44885 new int64(0x3956c25b, -213338824), new int64(0x59f111f1, -1241133031),
44886 new int64(-1841331548, -1357295717), new int64(-1424204075, -630357736),
44887 new int64(-670586216, -1560083902), new int64(0x12835b01, 0x45706fbe),
44888 new int64(0x243185be, 0x4ee4b28c), new int64(0x550c7dc3, -704662302),
44889 new int64(0x72be5d74, -226784913), new int64(-2132889090, 0x3b1696b1),
44890 new int64(-1680079193, 0x25c71235), new int64(-1046744716, -815192428),
44891 new int64(-459576895, -1628353838), new int64(-272742522, 0x384f25e3),
44892 new int64(0xfc19dc6, -1953704523), new int64(0x240ca1cc, 0x77ac9c65),
44893 new int64(0x2de92c6f, 0x592b0275), new int64(0x4a7484aa, 0x6ea6e483),
44894 new int64(0x5cb0a9dc, -1119749164), new int64(0x76f988da, -2096016459),
44895 new int64(-1740746414, -295247957), new int64(-1473132947, 0x2db43210),
44896 new int64(-1341970488, -1728372417), new int64(-1084653625, -1091629340),
44897 new int64(-958395405, 0x3da88fc2), new int64(-710438585, -1828018395),
44898 new int64(0x6ca6351, -536640913), new int64(0x14292967, 0xa0e6e70),
44899 new int64(0x27b70a85, 0x46d22ffc), new int64(0x2e1b2138, 0x5c26c926),
44900 new int64(0x4d2c6dfc, 0x5ac42aed), new int64(0x53380d13, -1651133473),
44901 new int64(0x650a7354, -1951439906), new int64(0x766a0abb, 0x3c77b2a8),
44902 new int64(-2117940946, 0x47edaee6), new int64(-1838011259, 0x1482353b),
44903 new int64(-1564481375, 0x4cf10364), new int64(-1474664885, -1136513023),
44904 new int64(-1035236496, -789014639), new int64(-949202525, 0x654be30),
44905 new int64(-778901479, -688958952), new int64(-694614492, 0x5565a910),
44906 new int64(-200395387, 0x5771202a), new int64(0x106aa070, 0x32bbd1b8),
44907 new int64(0x19a4c116, -1194143544), new int64(0x1e376c08, 0x5141ab53),
44908 new int64(0x2748774c, -544281703), new int64(0x34b0bcb5, -509917016),
44909 new int64(0x391c0cb3, -976659869), new int64(0x4ed8aa4a, -482243893),
44910 new int64(0x5b9cca4f, 0x7763e373), new int64(0x682e6ff3, -692930397),
44911 new int64(0x748f82ee, 0x5defb2fc), new int64(0x78a5636f, 0x43172f60),
44912 new int64(-2067236844, -1578062990), new int64(-1933114872, 0x1a6439ec),
44913 new int64(-1866530822, 0x23631e28), new int64(-1538233109, -561857047),
44914 new int64(-1090935817, -1295615723), new int64(-965641998, -479046869),
44915 new int64(-903397682, -366583396), new int64(-779700025, 0x21c0c207),
44916 new int64(-354779690, -840897762), new int64(-176337025, -294727304),
44917 new int64(0x6f067aa, 0x72176fba), new int64(0xa637dc5, -1563912026),
44918 new int64(0x113f9804, -1090974290), new int64(0x1b710b35, 0x131c471b),
44919 new int64(0x28db77f5, 0x23047d84), new int64(0x32caab7b, 0x40c72493),
44920 new int64(0x3c9ebe0a, 0x15c9bebc), new int64(0x431d67c4, -1676669620),
44921 new int64(0x4cc5d4be, -885112138), new int64(0x597f299c, -60457430),
44922 new int64(0x5fcb6fab, 0x3ad6faec), new int64(0x6c44198c, 0x4a475817)
44926 for (i = 0; i < 80; i += 1) {
44927 W[i] = new int64(0, 0);
44930 // append padding to the source string. The format is described in the FIPS.
44931 x[len >> 5] |= 0x80 << (24 - (len & 0x1f));
44932 x[((len + 128 >> 10) << 5) + 31] = len;
44934 for (i = 0; i < l; i += 32) { //32 dwords is the block size
44935 int64copy(a, H[0]);
44936 int64copy(b, H[1]);
44937 int64copy(c, H[2]);
44938 int64copy(d, H[3]);
44939 int64copy(e, H[4]);
44940 int64copy(f, H[5]);
44941 int64copy(g, H[6]);
44942 int64copy(h, H[7]);
44944 for (j = 0; j < 16; j += 1) {
44945 W[j].h = x[i + 2 * j];
44946 W[j].l = x[i + 2 * j + 1];
44949 for (j = 16; j < 80; j += 1) {
44951 int64rrot(r1, W[j - 2], 19);
44952 int64revrrot(r2, W[j - 2], 29);
44953 int64shr(r3, W[j - 2], 6);
44954 s1.l = r1.l ^ r2.l ^ r3.l;
44955 s1.h = r1.h ^ r2.h ^ r3.h;
44957 int64rrot(r1, W[j - 15], 1);
44958 int64rrot(r2, W[j - 15], 8);
44959 int64shr(r3, W[j - 15], 7);
44960 s0.l = r1.l ^ r2.l ^ r3.l;
44961 s0.h = r1.h ^ r2.h ^ r3.h;
44963 int64add4(W[j], s1, W[j - 7], s0, W[j - 16]);
44966 for (j = 0; j < 80; j += 1) {
44968 Ch.l = (e.l & f.l) ^ (~e.l & g.l);
44969 Ch.h = (e.h & f.h) ^ (~e.h & g.h);
44972 int64rrot(r1, e, 14);
44973 int64rrot(r2, e, 18);
44974 int64revrrot(r3, e, 9);
44975 s1.l = r1.l ^ r2.l ^ r3.l;
44976 s1.h = r1.h ^ r2.h ^ r3.h;
44979 int64rrot(r1, a, 28);
44980 int64revrrot(r2, a, 2);
44981 int64revrrot(r3, a, 7);
44982 s0.l = r1.l ^ r2.l ^ r3.l;
44983 s0.h = r1.h ^ r2.h ^ r3.h;
44986 Maj.l = (a.l & b.l) ^ (a.l & c.l) ^ (b.l & c.l);
44987 Maj.h = (a.h & b.h) ^ (a.h & c.h) ^ (b.h & c.h);
44989 int64add5(T1, h, s1, Ch, sha512_k[j], W[j]);
44990 int64add(T2, s0, Maj);
44995 int64add(e, d, T1);
44999 int64add(a, T1, T2);
45001 int64add(H[0], H[0], a);
45002 int64add(H[1], H[1], b);
45003 int64add(H[2], H[2], c);
45004 int64add(H[3], H[3], d);
45005 int64add(H[4], H[4], e);
45006 int64add(H[5], H[5], f);
45007 int64add(H[6], H[6], g);
45008 int64add(H[7], H[7], h);
45011 //represent the hash as an array of 32-bit dwords
45012 for (i = 0; i < 8; i += 1) {
45013 hash[2 * i] = H[i].h;
45014 hash[2 * i + 1] = H[i].l;
45019 //A constructor for 64-bit numbers
45021 function int64(h, l) {
45024 //this.toString = int64toString;
45027 //Copies src into dst, assuming both are 64-bit numbers
45029 function int64copy(dst, src) {
45034 //Right-rotates a 64-bit number by shift
45035 //Won't handle cases of shift>=32
45036 //The function revrrot() is for that
45038 function int64rrot(dst, x, shift) {
45039 dst.l = (x.l >>> shift) | (x.h << (32 - shift));
45040 dst.h = (x.h >>> shift) | (x.l << (32 - shift));
45043 //Reverses the dwords of the source and then rotates right by shift.
45044 //This is equivalent to rotation by 32+shift
45046 function int64revrrot(dst, x, shift) {
45047 dst.l = (x.h >>> shift) | (x.l << (32 - shift));
45048 dst.h = (x.l >>> shift) | (x.h << (32 - shift));
45051 //Bitwise-shifts right a 64-bit number by shift
45052 //Won't handle shift>=32, but it's never needed in SHA512
45054 function int64shr(dst, x, shift) {
45055 dst.l = (x.l >>> shift) | (x.h << (32 - shift));
45056 dst.h = (x.h >>> shift);
45059 //Adds two 64-bit numbers
45060 //Like the original implementation, does not rely on 32-bit operations
45062 function int64add(dst, x, y) {
45063 var w0 = (x.l & 0xffff) + (y.l & 0xffff);
45064 var w1 = (x.l >>> 16) + (y.l >>> 16) + (w0 >>> 16);
45065 var w2 = (x.h & 0xffff) + (y.h & 0xffff) + (w1 >>> 16);
45066 var w3 = (x.h >>> 16) + (y.h >>> 16) + (w2 >>> 16);
45067 dst.l = (w0 & 0xffff) | (w1 << 16);
45068 dst.h = (w2 & 0xffff) | (w3 << 16);
45071 //Same, except with 4 addends. Works faster than adding them one by one.
45073 function int64add4(dst, a, b, c, d) {
45074 var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff);
45075 var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (w0 >>> 16);
45076 var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (w1 >>> 16);
45077 var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (w2 >>> 16);
45078 dst.l = (w0 & 0xffff) | (w1 << 16);
45079 dst.h = (w2 & 0xffff) | (w3 << 16);
45082 //Same, except with 5 addends
45084 function int64add5(dst, a, b, c, d, e) {
45085 var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff) + (e.l & 0xffff),
45086 w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (e.l >>> 16) + (w0 >>> 16),
45087 w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (e.h & 0xffff) + (w1 >>> 16),
45088 w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (e.h >>> 16) + (w2 >>> 16);
45089 dst.l = (w0 & 0xffff) | (w1 << 16);
45090 dst.h = (w2 & 0xffff) | (w3 << 16);
45094 * @class Hashes.RMD160
45096 * @param {Object} [config]
45098 * A JavaScript implementation of the RIPEMD-160 Algorithm
45099 * Version 2.2 Copyright Jeremy Lin, Paul Johnston 2000 - 2009.
45100 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
45101 * See http://pajhome.org.uk/crypt/md5 for details.
45102 * Also http://www.ocf.berkeley.edu/~jjlin/jsotp/
45104 RMD160: function(options) {
45106 * Private properties configuration variables. You may need to tweak these to be compatible with
45107 * the server-side, but the defaults work in most cases.
45108 * @see this.setUpperCase() method
45109 * @see this.setPad() method
45111 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false,
45112 /* hexadecimal output case format. false - lowercase; true - uppercase */
45113 b64pad = (options && typeof options.pad === 'string') ? options.pda : '=',
45114 /* base-64 pad character. Default '=' for strict RFC compliance */
45115 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
45116 /* enable/disable utf8 encoding */
45118 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
45119 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
45120 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
45121 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
45122 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
45125 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
45126 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
45127 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
45128 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
45129 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
45132 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
45133 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
45134 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
45135 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
45136 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
45139 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
45140 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
45141 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
45142 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
45143 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
45146 /* privileged (public) methods */
45147 this.hex = function(s) {
45148 return rstr2hex(rstr(s, utf8));
45150 this.b64 = function(s) {
45151 return rstr2b64(rstr(s, utf8), b64pad);
45153 this.any = function(s, e) {
45154 return rstr2any(rstr(s, utf8), e);
45156 this.raw = function(s) {
45157 return rstr(s, utf8);
45159 this.hex_hmac = function(k, d) {
45160 return rstr2hex(rstr_hmac(k, d));
45162 this.b64_hmac = function(k, d) {
45163 return rstr2b64(rstr_hmac(k, d), b64pad);
45165 this.any_hmac = function(k, d, e) {
45166 return rstr2any(rstr_hmac(k, d), e);
45169 * Perform a simple self-test to see if the VM is working
45170 * @return {String} Hexadecimal hash sample
45173 this.vm_test = function() {
45174 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
45177 * @description Enable/disable uppercase hexadecimal returned string
45179 * @return {Object} this
45182 this.setUpperCase = function(a) {
45183 if (typeof a === 'boolean') {
45189 * @description Defines a base64 pad string
45190 * @param {string} Pad
45191 * @return {Object} this
45194 this.setPad = function(a) {
45195 if (typeof a !== 'undefined') {
45201 * @description Defines a base64 pad string
45203 * @return {Object} this
45206 this.setUTF8 = function(a) {
45207 if (typeof a === 'boolean') {
45213 /* private methods */
45216 * Calculate the rmd160 of a raw string
45220 s = (utf8) ? utf8Encode(s) : s;
45221 return binl2rstr(binl(rstr2binl(s), s.length * 8));
45225 * Calculate the HMAC-rmd160 of a key and some data (raw strings)
45228 function rstr_hmac(key, data) {
45229 key = (utf8) ? utf8Encode(key) : key;
45230 data = (utf8) ? utf8Encode(data) : data;
45232 bkey = rstr2binl(key),
45236 if (bkey.length > 16) {
45237 bkey = binl(bkey, key.length * 8);
45240 for (i = 0; i < 16; i += 1) {
45241 ipad[i] = bkey[i] ^ 0x36363636;
45242 opad[i] = bkey[i] ^ 0x5C5C5C5C;
45244 hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
45245 return binl2rstr(binl(opad.concat(hash), 512 + 160));
45249 * Convert an array of little-endian words to a string
45252 function binl2rstr(input) {
45253 var i, output = '',
45254 l = input.length * 32;
45255 for (i = 0; i < l; i += 8) {
45256 output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
45262 * Calculate the RIPE-MD160 of an array of little-endian words, and a bit length.
45265 function binl(x, len) {
45272 A1, B1, C1, D1, E1,
45273 A2, B2, C2, D2, E2;
45275 /* append padding */
45276 x[len >> 5] |= 0x80 << (len % 32);
45277 x[(((len + 64) >>> 9) << 4) + 14] = len;
45280 for (i = 0; i < l; i += 16) {
45286 for (j = 0; j <= 79; j += 1) {
45287 T = safe_add(A1, rmd160_f(j, B1, C1, D1));
45288 T = safe_add(T, x[i + rmd160_r1[j]]);
45289 T = safe_add(T, rmd160_K1(j));
45290 T = safe_add(bit_rol(T, rmd160_s1[j]), E1);
45293 D1 = bit_rol(C1, 10);
45296 T = safe_add(A2, rmd160_f(79 - j, B2, C2, D2));
45297 T = safe_add(T, x[i + rmd160_r2[j]]);
45298 T = safe_add(T, rmd160_K2(j));
45299 T = safe_add(bit_rol(T, rmd160_s2[j]), E2);
45302 D2 = bit_rol(C2, 10);
45307 T = safe_add(h1, safe_add(C1, D2));
45308 h1 = safe_add(h2, safe_add(D1, E2));
45309 h2 = safe_add(h3, safe_add(E1, A2));
45310 h3 = safe_add(h4, safe_add(A1, B2));
45311 h4 = safe_add(h0, safe_add(B1, C2));
45314 return [h0, h1, h2, h3, h4];
45317 // specific algorithm methods
45319 function rmd160_f(j, x, y, z) {
45320 return (0 <= j && j <= 15) ? (x ^ y ^ z) :
45321 (16 <= j && j <= 31) ? (x & y) | (~x & z) :
45322 (32 <= j && j <= 47) ? (x | ~y) ^ z :
45323 (48 <= j && j <= 63) ? (x & z) | (y & ~z) :
45324 (64 <= j && j <= 79) ? x ^ (y | ~z) :
45325 'rmd160_f: j out of range';
45328 function rmd160_K1(j) {
45329 return (0 <= j && j <= 15) ? 0x00000000 :
45330 (16 <= j && j <= 31) ? 0x5a827999 :
45331 (32 <= j && j <= 47) ? 0x6ed9eba1 :
45332 (48 <= j && j <= 63) ? 0x8f1bbcdc :
45333 (64 <= j && j <= 79) ? 0xa953fd4e :
45334 'rmd160_K1: j out of range';
45337 function rmd160_K2(j) {
45338 return (0 <= j && j <= 15) ? 0x50a28be6 :
45339 (16 <= j && j <= 31) ? 0x5c4dd124 :
45340 (32 <= j && j <= 47) ? 0x6d703ef3 :
45341 (48 <= j && j <= 63) ? 0x7a6d76e9 :
45342 (64 <= j && j <= 79) ? 0x00000000 :
45343 'rmd160_K2: j out of range';
45349 (function(window, undefined) {
45350 var freeExports = false;
45351 if (typeof exports === 'object') {
45352 freeExports = exports;
45353 if (exports && typeof commonjsGlobal === 'object' && commonjsGlobal && commonjsGlobal === commonjsGlobal.global) {
45354 window = commonjsGlobal;
45358 if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
45359 // define as an anonymous module, so, through path mapping, it can be aliased
45360 define(function() {
45363 } else if (freeExports) {
45364 // in Node.js or RingoJS v0.8.0+
45365 if (typeof module === 'object' && module && module.exports === freeExports) {
45366 module.exports = Hashes;
45368 // in Narwhal or RingoJS v0.7.0-
45370 freeExports.Hashes = Hashes;
45373 // in a browser or Rhino
45374 window.Hashes = Hashes;
45380 var immutable = extend$2;
45382 var hasOwnProperty = Object.prototype.hasOwnProperty;
45384 function extend$2() {
45387 for (var i = 0; i < arguments.length; i++) {
45388 var source = arguments[i];
45390 for (var key in source) {
45391 if (hasOwnProperty.call(source, key)) {
45392 target[key] = source[key];
45400 var hashes = hashes$1;
45401 var xtend$1 = immutable;
45402 var sha1 = new hashes.SHA1();
45406 ohauth$1.qsString = function(obj) {
45407 return Object.keys(obj).sort().map(function(key) {
45408 return ohauth$1.percentEncode(key) + '=' +
45409 ohauth$1.percentEncode(obj[key]);
45413 ohauth$1.stringQs = function(str) {
45414 return str.split('&').filter(function (pair) {
45415 return pair !== '';
45416 }).reduce(function(obj, pair){
45417 var parts = pair.split('=');
45418 obj[decodeURIComponent(parts[0])] = (null === parts[1]) ?
45419 '' : decodeURIComponent(parts[1]);
45424 ohauth$1.rawxhr = function(method, url, data, headers, callback) {
45425 var xhr = new XMLHttpRequest(),
45426 twoHundred = /^20\d$/;
45427 xhr.onreadystatechange = function() {
45428 if (4 === xhr.readyState && 0 !== xhr.status) {
45429 if (twoHundred.test(xhr.status)) callback(null, xhr);
45430 else return callback(xhr, null);
45433 xhr.onerror = function(e) { return callback(e, null); };
45434 xhr.open(method, url, true);
45435 for (var h in headers) xhr.setRequestHeader(h, headers[h]);
45440 ohauth$1.xhr = function(method, url, auth, data, options, callback) {
45441 var headers = (options && options.header) || {
45442 'Content-Type': 'application/x-www-form-urlencoded'
45444 headers.Authorization = 'OAuth ' + ohauth$1.authHeader(auth);
45445 return ohauth$1.rawxhr(method, url, data, headers, callback);
45448 ohauth$1.nonce = function() {
45449 for (var o = ''; o.length < 6;) {
45450 o += '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'[Math.floor(Math.random() * 61)];
45455 ohauth$1.authHeader = function(obj) {
45456 return Object.keys(obj).sort().map(function(key) {
45457 return encodeURIComponent(key) + '="' + encodeURIComponent(obj[key]) + '"';
45461 ohauth$1.timestamp = function() { return ~~((+new Date()) / 1000); };
45463 ohauth$1.percentEncode = function(s) {
45464 return encodeURIComponent(s)
45465 .replace(/\!/g, '%21').replace(/\'/g, '%27')
45466 .replace(/\*/g, '%2A').replace(/\(/g, '%28').replace(/\)/g, '%29');
45469 ohauth$1.baseString = function(method, url, params) {
45470 if (params.oauth_signature) delete params.oauth_signature;
45473 ohauth$1.percentEncode(url),
45474 ohauth$1.percentEncode(ohauth$1.qsString(params))].join('&');
45477 ohauth$1.signature = function(oauth_secret, token_secret, baseString) {
45478 return sha1.b64_hmac(
45479 ohauth$1.percentEncode(oauth_secret) + '&' +
45480 ohauth$1.percentEncode(token_secret),
45485 * Takes an options object for configuration (consumer_key,
45486 * consumer_secret, version, signature_method, token, token_secret)
45487 * and returns a function that generates the Authorization header
45490 * The returned function takes these parameters:
45491 * - method: GET/POST/...
45492 * - uri: full URI with protocol, port, path and query string
45493 * - extra_params: any extra parameters (that are passed in the POST data),
45494 * can be an object or a from-urlencoded string.
45496 * Returned function returns full OAuth header with "OAuth" string in it.
45499 ohauth$1.headerGenerator = function(options) {
45500 options = options || {};
45501 var consumer_key = options.consumer_key || '',
45502 consumer_secret = options.consumer_secret || '',
45503 signature_method = options.signature_method || 'HMAC-SHA1',
45504 version = options.version || '1.0',
45505 token = options.token || '',
45506 token_secret = options.token_secret || '';
45508 return function(method, uri, extra_params) {
45509 method = method.toUpperCase();
45510 if (typeof extra_params === 'string' && extra_params.length > 0) {
45511 extra_params = ohauth$1.stringQs(extra_params);
45514 var uri_parts = uri.split('?', 2),
45515 base_uri = uri_parts[0];
45517 var query_params = uri_parts.length === 2 ?
45518 ohauth$1.stringQs(uri_parts[1]) : {};
45520 var oauth_params = {
45521 oauth_consumer_key: consumer_key,
45522 oauth_signature_method: signature_method,
45523 oauth_version: version,
45524 oauth_timestamp: ohauth$1.timestamp(),
45525 oauth_nonce: ohauth$1.nonce()
45528 if (token) oauth_params.oauth_token = token;
45530 var all_params = xtend$1({}, oauth_params, query_params, extra_params),
45531 base_str = ohauth$1.baseString(method, base_uri, all_params);
45533 oauth_params.oauth_signature = ohauth$1.signature(consumer_secret, token_secret, base_str);
45535 return 'OAuth ' + ohauth$1.authHeader(oauth_params);
45539 var index$12 = ohauth$1;
45541 var store$1 = createCommonjsModule(function (module, exports) {
45543 // Module export pattern from
45544 // https://github.com/umdjs/umd/blob/master/returnExports.js
45545 ;(function (root, factory) {
45546 if (typeof define === 'function' && define.amd) {
45547 // AMD. Register as an anonymous module.
45548 define([], factory);
45549 } else if (typeof exports === 'object') {
45550 // Node. Does not work with strict CommonJS, but
45551 // only CommonJS-like environments that support module.exports,
45553 module.exports = factory();
45555 // Browser globals (root is window)
45556 root.store = factory();
45558 }(commonjsGlobal, function () {
45562 win = (typeof window != 'undefined' ? window : commonjsGlobal),
45563 doc = win.document,
45564 localStorageName = 'localStorage',
45565 scriptTag = 'script',
45568 store.disabled = false;
45569 store.version = '1.3.20';
45570 store.set = function(key, value) {};
45571 store.get = function(key, defaultVal) {};
45572 store.has = function(key) { return store.get(key) !== undefined };
45573 store.remove = function(key) {};
45574 store.clear = function() {};
45575 store.transact = function(key, defaultVal, transactionFn) {
45576 if (transactionFn == null) {
45577 transactionFn = defaultVal;
45580 if (defaultVal == null) {
45583 var val = store.get(key, defaultVal);
45584 transactionFn(val);
45585 store.set(key, val);
45587 store.getAll = function() {};
45588 store.forEach = function() {};
45590 store.serialize = function(value) {
45591 return JSON.stringify(value)
45593 store.deserialize = function(value) {
45594 if (typeof value != 'string') { return undefined }
45595 try { return JSON.parse(value) }
45596 catch(e) { return value || undefined }
45599 // Functions to encapsulate questionable FireFox 3.6.13 behavior
45600 // when about.config::dom.storage.enabled === false
45601 // See https://github.com/marcuswestin/store.js/issues#issue/13
45602 function isLocalStorageNameSupported() {
45603 try { return (localStorageName in win && win[localStorageName]) }
45604 catch(err) { return false }
45607 if (isLocalStorageNameSupported()) {
45608 storage = win[localStorageName];
45609 store.set = function(key, val) {
45610 if (val === undefined) { return store.remove(key) }
45611 storage.setItem(key, store.serialize(val));
45614 store.get = function(key, defaultVal) {
45615 var val = store.deserialize(storage.getItem(key));
45616 return (val === undefined ? defaultVal : val)
45618 store.remove = function(key) { storage.removeItem(key); };
45619 store.clear = function() { storage.clear(); };
45620 store.getAll = function() {
45622 store.forEach(function(key, val) {
45627 store.forEach = function(callback) {
45628 for (var i=0; i<storage.length; i++) {
45629 var key = storage.key(i);
45630 callback(key, store.get(key));
45633 } else if (doc && doc.documentElement.addBehavior) {
45636 // Since #userData storage applies only to specific paths, we need to
45637 // somehow link our data to a specific path. We choose /favicon.ico
45638 // as a pretty safe option, since all browsers already make a request to
45639 // this URL anyway and being a 404 will not hurt us here. We wrap an
45640 // iframe pointing to the favicon in an ActiveXObject(htmlfile) object
45641 // (see: http://msdn.microsoft.com/en-us/library/aa752574(v=VS.85).aspx)
45642 // since the iframe access rules appear to allow direct access and
45643 // manipulation of the document element, even for a 404 page. This
45644 // document can be used instead of the current document (which would
45645 // have been limited to the current path) to perform #userData storage.
45647 storageContainer = new ActiveXObject('htmlfile');
45648 storageContainer.open();
45649 storageContainer.write('<'+scriptTag+'>document.w=window</'+scriptTag+'><iframe src="/favicon.ico"></iframe>');
45650 storageContainer.close();
45651 storageOwner = storageContainer.w.frames[0].document;
45652 storage = storageOwner.createElement('div');
45654 // somehow ActiveXObject instantiation failed (perhaps some special
45655 // security settings or otherwse), fall back to per-path storage
45656 storage = doc.createElement('div');
45657 storageOwner = doc.body;
45659 var withIEStorage = function(storeFunction) {
45660 return function() {
45661 var args = Array.prototype.slice.call(arguments, 0);
45662 args.unshift(storage);
45663 // See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx
45664 // and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx
45665 storageOwner.appendChild(storage);
45666 storage.addBehavior('#default#userData');
45667 storage.load(localStorageName);
45668 var result = storeFunction.apply(store, args);
45669 storageOwner.removeChild(storage);
45674 // In IE7, keys cannot start with a digit or contain certain chars.
45675 // See https://github.com/marcuswestin/store.js/issues/40
45676 // See https://github.com/marcuswestin/store.js/issues/83
45677 var forbiddenCharsRegex = new RegExp("[!\"#$%&'()*+,/\\\\:;<=>?@[\\]^`{|}~]", "g");
45678 var ieKeyFix = function(key) {
45679 return key.replace(/^d/, '___$&').replace(forbiddenCharsRegex, '___')
45681 store.set = withIEStorage(function(storage, key, val) {
45682 key = ieKeyFix(key);
45683 if (val === undefined) { return store.remove(key) }
45684 storage.setAttribute(key, store.serialize(val));
45685 storage.save(localStorageName);
45688 store.get = withIEStorage(function(storage, key, defaultVal) {
45689 key = ieKeyFix(key);
45690 var val = store.deserialize(storage.getAttribute(key));
45691 return (val === undefined ? defaultVal : val)
45693 store.remove = withIEStorage(function(storage, key) {
45694 key = ieKeyFix(key);
45695 storage.removeAttribute(key);
45696 storage.save(localStorageName);
45698 store.clear = withIEStorage(function(storage) {
45699 var attributes = storage.XMLDocument.documentElement.attributes;
45700 storage.load(localStorageName);
45701 for (var i=attributes.length-1; i>=0; i--) {
45702 storage.removeAttribute(attributes[i].name);
45704 storage.save(localStorageName);
45706 store.getAll = function(storage) {
45708 store.forEach(function(key, val) {
45713 store.forEach = withIEStorage(function(storage, callback) {
45714 var attributes = storage.XMLDocument.documentElement.attributes;
45715 for (var i=0, attr; attr=attributes[i]; ++i) {
45716 callback(attr.name, store.deserialize(storage.getAttribute(attr.name)));
45722 var testKey = '__storejs__';
45723 store.set(testKey, testKey);
45724 if (store.get(testKey) != testKey) { store.disabled = true; }
45725 store.remove(testKey);
45727 store.disabled = true;
45729 store.enabled = !store.disabled;
45735 var ohauth = index$12;
45736 var xtend = immutable;
45737 var store = store$1;
45741 // This code is only compatible with IE10+ because the [XDomainRequest](http://bit.ly/LfO7xo)
45742 // object, IE<10's idea of [CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing),
45743 // does not support custom headers, which this uses everywhere.
45744 var index$11 = function(o) {
45748 // authenticated users will also have a request token secret, but it's
45749 // not used in transactions with the server
45750 oauth.authenticated = function() {
45751 return !!(token('oauth_token') && token('oauth_token_secret'));
45754 oauth.logout = function() {
45755 token('oauth_token', '');
45756 token('oauth_token_secret', '');
45757 token('oauth_request_token_secret', '');
45761 // TODO: detect lack of click event
45762 oauth.authenticate = function(callback) {
45763 if (oauth.authenticated()) return callback();
45767 // ## Getting a request token
45768 var params = timenonce(getAuth(o)),
45769 url = o.url + '/oauth/request_token';
45771 params.oauth_signature = ohauth.signature(
45772 o.oauth_secret, '',
45773 ohauth.baseString('POST', url, params));
45775 if (!o.singlepage) {
45776 // Create a 600x550 popup window in the center of the screen
45777 var w = 600, h = 550,
45779 ['width', w], ['height', h],
45780 ['left', screen.width / 2 - w / 2],
45781 ['top', screen.height / 2 - h / 2]].map(function(x) {
45782 return x.join('=');
45784 popup = window.open('about:blank', 'oauth_window', settings);
45787 // Request a request token. When this is complete, the popup
45788 // window is redirected to OSM's authorization page.
45789 ohauth.xhr('POST', url, params, null, {}, reqTokenDone);
45792 function reqTokenDone(err, xhr) {
45794 if (err) return callback(err);
45795 var resp = ohauth.stringQs(xhr.response);
45796 token('oauth_request_token_secret', resp.oauth_token_secret);
45797 var authorize_url = o.url + '/oauth/authorize?' + ohauth.qsString({
45798 oauth_token: resp.oauth_token,
45799 oauth_callback: location.href.replace('index.html', '')
45800 .replace(/#.*/, '').replace(location.search, '') + o.landing
45803 if (o.singlepage) {
45804 location.href = authorize_url;
45806 popup.location = authorize_url;
45810 // Called by a function in a landing page, in the popup window. The
45811 // window closes itself.
45812 window.authComplete = function(token) {
45813 var oauth_token = ohauth.stringQs(token.split('?')[1]);
45814 get_access_token(oauth_token.oauth_token);
45815 delete window.authComplete;
45818 // ## Getting an request token
45820 // At this point we have an `oauth_token`, brought in from a function
45821 // call on a landing page popup.
45822 function get_access_token(oauth_token) {
45823 var url = o.url + '/oauth/access_token',
45824 params = timenonce(getAuth(o)),
45825 request_token_secret = token('oauth_request_token_secret');
45826 params.oauth_token = oauth_token;
45827 params.oauth_signature = ohauth.signature(
45829 request_token_secret,
45830 ohauth.baseString('POST', url, params));
45832 // ## Getting an access token
45834 // The final token required for authentication. At this point
45835 // we have a `request token secret`
45836 ohauth.xhr('POST', url, params, null, {}, accessTokenDone);
45840 function accessTokenDone(err, xhr) {
45842 if (err) return callback(err);
45843 var access_token = ohauth.stringQs(xhr.response);
45844 token('oauth_token', access_token.oauth_token);
45845 token('oauth_token_secret', access_token.oauth_token_secret);
45846 callback(null, oauth);
45850 oauth.bootstrapToken = function(oauth_token, callback) {
45851 // ## Getting an request token
45852 // At this point we have an `oauth_token`, brought in from a function
45853 // call on a landing page popup.
45854 function get_access_token(oauth_token) {
45855 var url = o.url + '/oauth/access_token',
45856 params = timenonce(getAuth(o)),
45857 request_token_secret = token('oauth_request_token_secret');
45858 params.oauth_token = oauth_token;
45859 params.oauth_signature = ohauth.signature(
45861 request_token_secret,
45862 ohauth.baseString('POST', url, params));
45864 // ## Getting an access token
45865 // The final token required for authentication. At this point
45866 // we have a `request token secret`
45867 ohauth.xhr('POST', url, params, null, {}, accessTokenDone);
45871 function accessTokenDone(err, xhr) {
45873 if (err) return callback(err);
45874 var access_token = ohauth.stringQs(xhr.response);
45875 token('oauth_token', access_token.oauth_token);
45876 token('oauth_token_secret', access_token.oauth_token_secret);
45877 callback(null, oauth);
45880 get_access_token(oauth_token);
45885 // A single XMLHttpRequest wrapper that does authenticated calls if the
45886 // user has logged in.
45887 oauth.xhr = function(options, callback) {
45888 if (!oauth.authenticated()) {
45890 return oauth.authenticate(run);
45892 callback('not authenticated', null);
45900 var params = timenonce(getAuth(o)),
45901 oauth_token_secret = token('oauth_token_secret'),
45902 url = (options.prefix !== false) ? o.url + options.path : options.path,
45903 url_parts = url.replace(/#.*$/, '').split('?', 2),
45904 base_url = url_parts[0],
45905 query = (url_parts.length === 2) ? url_parts[1] : '';
45907 // https://tools.ietf.org/html/rfc5849#section-3.4.1.3.1
45908 if ((!options.options || !options.options.header ||
45909 options.options.header['Content-Type'] === 'application/x-www-form-urlencoded') &&
45911 params = xtend(params, ohauth.stringQs(options.content));
45914 params.oauth_token = token('oauth_token');
45915 params.oauth_signature = ohauth.signature(
45917 oauth_token_secret,
45918 ohauth.baseString(options.method, base_url, xtend(params, ohauth.stringQs(query)))
45921 return ohauth.xhr(options.method, url, params, options.content, options.options, done);
45924 function done(err, xhr) {
45925 if (err) return callback(err);
45926 else if (xhr.responseXML) return callback(err, xhr.responseXML);
45927 else return callback(err, xhr.response);
45931 // pre-authorize this object, if we can just get a token and token_secret
45933 oauth.preauth = function(c) {
45935 if (c.oauth_token) token('oauth_token', c.oauth_token);
45936 if (c.oauth_token_secret) token('oauth_token_secret', c.oauth_token_secret);
45940 oauth.options = function(_) {
45941 if (!arguments.length) return o;
45944 o.url = o.url || 'http://www.openstreetmap.org';
45945 o.landing = o.landing || 'land.html';
45946 o.singlepage = o.singlepage || false;
45948 // Optional loading and loading-done functions for nice UI feedback.
45949 // by default, no-ops
45950 o.loading = o.loading || function() {};
45951 o.done = o.done || function() {};
45953 return oauth.preauth(o);
45956 // 'stamp' an authentication object from `getAuth()`
45957 // with a [nonce](http://en.wikipedia.org/wiki/Cryptographic_nonce)
45959 function timenonce(o) {
45960 o.oauth_timestamp = ohauth.timestamp();
45961 o.oauth_nonce = ohauth.nonce();
45965 // get/set tokens. These are prefixed with the base URL so that `osm-auth`
45966 // can be used with multiple APIs and the keys in `localStorage`
45970 if (store.enabled) {
45971 token = function (x, y) {
45972 if (arguments.length === 1) return store.get(o.url + x);
45973 else if (arguments.length === 2) return store.set(o.url + x, y);
45977 token = function (x, y) {
45978 if (arguments.length === 1) return storage[o.url + x];
45979 else if (arguments.length === 2) return storage[o.url + x] = y;
45983 // Get an authentication object. If you just add and remove properties
45984 // from a single object, you'll need to use `delete` to make sure that
45985 // it doesn't contain undesired properties for authentication
45986 function getAuth(o) {
45988 oauth_consumer_key: o.oauth_consumer_key,
45989 oauth_signature_method: 'HMAC-SHA1'
45993 // potentially pre-authorize
45999 var JXON = new (function () {
46001 sValueProp = 'keyValue', sAttributesProp = 'keyAttributes', sAttrPref = '@', /* you can customize these values */
46002 aCache = [], rIsNull = /^\s*$/, rIsBool = /^(?:true|false)$/i;
46004 function parseText (sValue) {
46005 if (rIsNull.test(sValue)) { return null; }
46006 if (rIsBool.test(sValue)) { return sValue.toLowerCase() === 'true'; }
46007 if (isFinite(sValue)) { return parseFloat(sValue); }
46008 if (isFinite(Date.parse(sValue))) { return new Date(sValue); }
46012 function EmptyTree () { }
46013 EmptyTree.prototype.toString = function () { return 'null'; };
46014 EmptyTree.prototype.valueOf = function () { return null; };
46016 function objectify (vValue) {
46017 return vValue === null ? new EmptyTree() : vValue instanceof Object ? vValue : new vValue.constructor(vValue);
46020 function createObjTree (oParentNode, nVerb, bFreeze, bNesteAttr) {
46022 nLevelStart = aCache.length, bChildren = oParentNode.hasChildNodes(),
46023 bAttributes = oParentNode.hasAttributes(), bHighVerb = Boolean(nVerb & 2);
46026 sProp, vContent, nLength = 0, sCollectedTxt = '',
46027 vResult = bHighVerb ? {} : /* put here the default value for empty nodes: */ true;
46030 for (var oNode, nItem = 0; nItem < oParentNode.childNodes.length; nItem++) {
46031 oNode = oParentNode.childNodes.item(nItem);
46032 if (oNode.nodeType === 4) { sCollectedTxt += oNode.nodeValue; } /* nodeType is 'CDATASection' (4) */
46033 else if (oNode.nodeType === 3) { sCollectedTxt += oNode.nodeValue.trim(); } /* nodeType is 'Text' (3) */
46034 else if (oNode.nodeType === 1 && !oNode.prefix) { aCache.push(oNode); } /* nodeType is 'Element' (1) */
46038 var nLevelEnd = aCache.length, vBuiltVal = parseText(sCollectedTxt);
46040 if (!bHighVerb && (bChildren || bAttributes)) { vResult = nVerb === 0 ? objectify(vBuiltVal) : {}; }
46042 for (var nElId = nLevelStart; nElId < nLevelEnd; nElId++) {
46043 sProp = aCache[nElId].nodeName.toLowerCase();
46044 vContent = createObjTree(aCache[nElId], nVerb, bFreeze, bNesteAttr);
46045 if (vResult.hasOwnProperty(sProp)) {
46046 if (vResult[sProp].constructor !== Array) { vResult[sProp] = [vResult[sProp]]; }
46047 vResult[sProp].push(vContent);
46049 vResult[sProp] = vContent;
46056 nAttrLen = oParentNode.attributes.length,
46057 sAPrefix = bNesteAttr ? '' : sAttrPref, oAttrParent = bNesteAttr ? {} : vResult;
46059 for (var oAttrib, nAttrib = 0; nAttrib < nAttrLen; nLength++, nAttrib++) {
46060 oAttrib = oParentNode.attributes.item(nAttrib);
46061 oAttrParent[sAPrefix + oAttrib.name.toLowerCase()] = parseText(oAttrib.value.trim());
46065 if (bFreeze) { Object.freeze(oAttrParent); }
46066 vResult[sAttributesProp] = oAttrParent;
46067 nLength -= nAttrLen - 1;
46071 if (nVerb === 3 || (nVerb === 2 || nVerb === 1 && nLength > 0) && sCollectedTxt) {
46072 vResult[sValueProp] = vBuiltVal;
46073 } else if (!bHighVerb && nLength === 0 && sCollectedTxt) {
46074 vResult = vBuiltVal;
46077 if (bFreeze && (bHighVerb || nLength > 0)) { Object.freeze(vResult); }
46079 aCache.length = nLevelStart;
46084 function loadObjTree (oXMLDoc, oParentEl, oParentObj) {
46085 var vValue, oChild;
46087 if (oParentObj instanceof String || oParentObj instanceof Number || oParentObj instanceof Boolean) {
46088 oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toString())); /* verbosity level is 0 */
46089 } else if (oParentObj.constructor === Date) {
46090 oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toGMTString()));
46093 for (var sName in oParentObj) {
46094 vValue = oParentObj[sName];
46095 if (isFinite(sName) || vValue instanceof Function) { continue; } /* verbosity level is 0 */
46096 if (sName === sValueProp) {
46097 if (vValue !== null && vValue !== true) { oParentEl.appendChild(oXMLDoc.createTextNode(vValue.constructor === Date ? vValue.toGMTString() : String(vValue))); }
46098 } else if (sName === sAttributesProp) { /* verbosity level is 3 */
46099 for (var sAttrib in vValue) { oParentEl.setAttribute(sAttrib, vValue[sAttrib]); }
46100 } else if (sName.charAt(0) === sAttrPref) {
46101 oParentEl.setAttribute(sName.slice(1), vValue);
46102 } else if (vValue.constructor === Array) {
46103 for (var nItem = 0; nItem < vValue.length; nItem++) {
46104 oChild = oXMLDoc.createElement(sName);
46105 loadObjTree(oXMLDoc, oChild, vValue[nItem]);
46106 oParentEl.appendChild(oChild);
46109 oChild = oXMLDoc.createElement(sName);
46110 if (vValue instanceof Object) {
46111 loadObjTree(oXMLDoc, oChild, vValue);
46112 } else if (vValue !== null && vValue !== true) {
46113 oChild.appendChild(oXMLDoc.createTextNode(vValue.toString()));
46115 oParentEl.appendChild(oChild);
46120 this.build = function (oXMLParent, nVerbosity /* optional */, bFreeze /* optional */, bNesteAttributes /* optional */) {
46121 var _nVerb = arguments.length > 1 && typeof nVerbosity === 'number' ? nVerbosity & 3 : /* put here the default verbosity level: */ 1;
46122 return createObjTree(oXMLParent, _nVerb, bFreeze || false, arguments.length > 3 ? bNesteAttributes : _nVerb === 3);
46125 this.unbuild = function (oObjTree) {
46126 var oNewDoc = document.implementation.createDocument('', '', null);
46127 loadObjTree(oNewDoc, oNewDoc, oObjTree);
46131 this.stringify = function (oObjTree) {
46132 return (new XMLSerializer()).serializeToString(JXON.unbuild(oObjTree));
46136 // var myObject = JXON.build(doc);
46137 // we got our javascript object! try: alert(JSON.stringify(myObject));
46139 // var newDoc = JXON.unbuild(myObject);
46140 // we got our Document instance! try: alert((new XMLSerializer()).serializeToString(newDoc));
46142 var dispatch$3 = dispatch('authLoading', 'authDone', 'change', 'loading', 'loaded');
46143 var useHttps = window.location.protocol === 'https:';
46144 var protocol = useHttps ? 'https:' : 'http:';
46145 var urlroot = protocol + '//www.openstreetmap.org';
46147 var loadedTiles = {};
46148 var tileZoom$1 = 16;
46149 var oauth = index$11({
46151 oauth_consumer_key: '5A043yRSEugj4DJ5TljuapfnrflWDte8jTOcWLlT',
46152 oauth_secret: 'aB3jKq1TRsCOUrfOIZ6oQMEDmv2ptV76PA54NGLL',
46153 loading: authLoading,
46156 var rateLimitError;
46161 function authLoading() {
46162 dispatch$3.call('authLoading');
46166 function authDone() {
46167 dispatch$3.call('authDone');
46171 function abortRequest$1(i) {
46178 function getLoc(attrs) {
46179 var lon = attrs.lon && attrs.lon.value,
46180 lat = attrs.lat && attrs.lat.value;
46181 return [parseFloat(lon), parseFloat(lat)];
46185 function getNodes(obj) {
46186 var elems = obj.getElementsByTagName('nd'),
46187 nodes = new Array(elems.length);
46188 for (var i = 0, l = elems.length; i < l; i++) {
46189 nodes[i] = 'n' + elems[i].attributes.ref.value;
46195 function getTags(obj) {
46196 var elems = obj.getElementsByTagName('tag'),
46198 for (var i = 0, l = elems.length; i < l; i++) {
46199 var attrs = elems[i].attributes;
46200 tags[attrs.k.value] = attrs.v.value;
46206 function getMembers(obj) {
46207 var elems = obj.getElementsByTagName('member'),
46208 members = new Array(elems.length);
46209 for (var i = 0, l = elems.length; i < l; i++) {
46210 var attrs = elems[i].attributes;
46212 id: attrs.type.value[0] + attrs.ref.value,
46213 type: attrs.type.value,
46214 role: attrs.role.value
46221 function getVisible(attrs) {
46222 return (!attrs.visible || attrs.visible.value !== 'false');
46227 node: function nodeData(obj) {
46228 var attrs = obj.attributes;
46229 return new osmNode({
46230 id: osmEntity$$1.id.fromOSM('node', attrs.id.value),
46231 loc: getLoc(attrs),
46232 version: attrs.version.value,
46233 user: attrs.user && attrs.user.value,
46234 tags: getTags(obj),
46235 visible: getVisible(attrs)
46239 way: function wayData(obj) {
46240 var attrs = obj.attributes;
46241 return new osmWay({
46242 id: osmEntity$$1.id.fromOSM('way', attrs.id.value),
46243 version: attrs.version.value,
46244 user: attrs.user && attrs.user.value,
46245 tags: getTags(obj),
46246 nodes: getNodes(obj),
46247 visible: getVisible(attrs)
46251 relation: function relationData(obj) {
46252 var attrs = obj.attributes;
46253 return new osmRelation({
46254 id: osmEntity$$1.id.fromOSM('relation', attrs.id.value),
46255 version: attrs.version.value,
46256 user: attrs.user && attrs.user.value,
46257 tags: getTags(obj),
46258 members: getMembers(obj),
46259 visible: getVisible(attrs)
46265 function parse(xml$$1) {
46266 if (!xml$$1 || !xml$$1.childNodes) return;
46268 var root = xml$$1.childNodes[0],
46269 children = root.childNodes,
46272 for (var i = 0, l = children.length; i < l; i++) {
46273 var child = children[i],
46274 parser = parsers[child.nodeName];
46276 entities.push(parser(child));
46287 utilRebind(this, dispatch$3, 'on');
46291 reset: function() {
46292 userDetails = undefined;
46293 rateLimitError = undefined;
46294 lodash.forEach(inflight, abortRequest$1);
46301 changesetURL: function(changesetId) {
46302 return urlroot + '/changeset/' + changesetId;
46306 changesetsURL: function(center, zoom$$1) {
46307 var precision = Math.max(0, Math.ceil(Math.log(zoom$$1) / Math.LN2));
46308 return urlroot + '/history#map=' +
46309 Math.floor(zoom$$1) + '/' +
46310 center[1].toFixed(precision) + '/' +
46311 center[0].toFixed(precision);
46315 entityURL: function(entity) {
46316 return urlroot + '/' + entity.type + '/' + entity.osmId();
46320 userURL: function(username) {
46321 return urlroot + '/user/' + username;
46325 loadFromAPI: function(path$$1, callback) {
46328 function done(err, xml$$1) {
46329 var isAuthenticated = that.authenticated();
46331 // 400 Bad Request, 401 Unauthorized, 403 Forbidden
46332 // Logout and retry the request..
46333 if (isAuthenticated && err &&
46334 (err.status === 400 || err.status === 401 || err.status === 403)) {
46336 that.loadFromAPI(path$$1, callback);
46338 // else, no retry..
46340 // 509 Bandwidth Limit Exceeded, 429 Too Many Requests
46341 // Set the rateLimitError flag and trigger a warning..
46342 if (!isAuthenticated && !rateLimitError && err &&
46343 (err.status === 509 || err.status === 429)) {
46344 rateLimitError = err;
46345 dispatch$3.call('change');
46349 callback(err, parse(xml$$1));
46354 if (this.authenticated()) {
46355 return oauth.xhr({ method: 'GET', path: path$$1 }, done);
46357 var url = urlroot + path$$1;
46358 return xml(url).get(done);
46363 loadEntity: function(id, callback) {
46364 var type = osmEntity$$1.id.type(id),
46365 osmID = osmEntity$$1.id.toOSM(id);
46368 '/api/0.6/' + type + '/' + osmID + (type !== 'node' ? '/full' : ''),
46369 function(err, entities) {
46370 if (callback) callback(err, { data: entities });
46376 loadEntityVersion: function(id, version$$1, callback) {
46377 var type = osmEntity$$1.id.type(id),
46378 osmID = osmEntity$$1.id.toOSM(id);
46381 '/api/0.6/' + type + '/' + osmID + '/' + version$$1,
46382 function(err, entities) {
46383 if (callback) callback(err, { data: entities });
46389 loadMultiple: function(ids, callback) {
46391 lodash.each(lodash.groupBy(lodash.uniq(ids), osmEntity$$1.id.type), function(v, k) {
46392 var type = k + 's',
46393 osmIDs = lodash.map(v, osmEntity$$1.id.toOSM);
46395 lodash.each(lodash.chunk(osmIDs, 150), function(arr) {
46397 '/api/0.6/' + type + '?' + type + '=' + arr.join(),
46398 function(err, entities) {
46399 if (callback) callback(err, { data: entities });
46407 authenticated: function() {
46408 return oauth.authenticated();
46412 // Generate Changeset XML. Returns a string.
46413 changesetJXON: function(tags) {
46417 tag: lodash.map(tags, function(value, key) {
46418 return { '@k': key, '@v': value };
46428 // Generate [osmChange](http://wiki.openstreetmap.org/wiki/OsmChange)
46429 // XML. Returns a string.
46430 osmChangeJXON: function(changeset_id, changes) {
46431 function nest$$1(x, order) {
46433 for (var i = 0; i < x.length; i++) {
46434 var tagName = Object.keys(x[i])[0];
46435 if (!groups[tagName]) groups[tagName] = [];
46436 groups[tagName].push(x[i][tagName]);
46439 order.forEach(function(o) {
46440 if (groups[o]) ordered[o] = groups[o];
46445 function rep(entity) {
46446 return entity.asJXON(changeset_id);
46452 '@generator': 'iD',
46453 'create': nest$$1(changes.created.map(rep), ['node', 'way', 'relation']),
46454 'modify': nest$$1(changes.modified.map(rep), ['node', 'way', 'relation']),
46455 'delete': lodash.extend(nest$$1(changes.deleted.map(rep), ['relation', 'way', 'node']), {'@if-unused': true})
46461 changesetTags: function(version$$1, comment, imageryUsed) {
46462 var detected = utilDetect(),
46464 created_by: ('iD ' + version$$1).substr(0, 255),
46465 imagery_used: imageryUsed.join(';').substr(0, 255),
46466 host: detected.host.substr(0, 255),
46467 locale: detected.locale.substr(0, 255)
46471 tags.comment = comment.substr(0, 255);
46478 putChangeset: function(changes, version$$1, comment, imageryUsed, callback) {
46482 path: '/api/0.6/changeset/create',
46483 options: { header: { 'Content-Type': 'text/xml' } },
46484 content: JXON.stringify(that.changesetJXON(that.changesetTags(version$$1, comment, imageryUsed)))
46485 }, function(err, changeset_id) {
46486 if (err) return callback(err);
46489 path: '/api/0.6/changeset/' + changeset_id + '/upload',
46490 options: { header: { 'Content-Type': 'text/xml' } },
46491 content: JXON.stringify(that.osmChangeJXON(changeset_id, changes))
46493 if (err) return callback(err);
46494 // POST was successful, safe to call the callback.
46495 // Still attempt to close changeset, but ignore response because #2667
46496 // Add delay to allow for postgres replication #1646 #2678
46497 window.setTimeout(function() { callback(null, changeset_id); }, 2500);
46500 path: '/api/0.6/changeset/' + changeset_id + '/close',
46501 options: { header: { 'Content-Type': 'text/xml' } }
46502 }, function() { return true; });
46508 userDetails: function(callback) {
46510 callback(undefined, userDetails);
46514 function done(err, user_details) {
46515 if (err) return callback(err);
46517 var u = user_details.getElementsByTagName('user')[0],
46518 img = u.getElementsByTagName('img'),
46521 if (img && img[0] && img[0].getAttribute('href')) {
46522 image_url = img[0].getAttribute('href');
46526 display_name: u.attributes.display_name.value,
46527 image_url: image_url,
46528 id: u.attributes.id.value
46531 callback(undefined, userDetails);
46534 oauth.xhr({ method: 'GET', path: '/api/0.6/user/details' }, done);
46538 userChangesets: function(callback) {
46539 this.userDetails(function(err, user) {
46545 function done(err, changesets) {
46549 callback(undefined, Array.prototype.map.call(changesets.getElementsByTagName('changeset'),
46550 function (changeset) {
46551 return { tags: getTags(changeset) };
46557 oauth.xhr({ method: 'GET', path: '/api/0.6/changesets?user=' + user.id }, done);
46562 status: function(callback) {
46563 function done(capabilities) {
46564 if (rateLimitError) {
46565 callback(rateLimitError, 'rateLimited');
46567 var apiStatus = capabilities.getElementsByTagName('status'),
46568 val = apiStatus[0].getAttribute('api');
46569 callback(undefined, val);
46572 xml(urlroot + '/api/capabilities').get()
46574 .on('error', callback);
46578 tileZoom: function(_) {
46579 if (!arguments.length) return tileZoom$1;
46585 loadTiles: function(projection, dimensions, callback) {
46589 s = projection.scale() * 2 * Math.PI,
46590 z = Math.max(Math.log(s) / Math.log(2) - 8, 0),
46591 ts = 256 * Math.pow(2, z - tileZoom$1),
46593 s / 2 - projection.translate()[0],
46594 s / 2 - projection.translate()[1]
46597 var tiles = d3geoTile()
46598 .scaleExtent([tileZoom$1, tileZoom$1])
46601 .translate(projection.translate())()
46602 .map(function(tile) {
46603 var x = tile[0] * ts - origin[0],
46604 y = tile[1] * ts - origin[1];
46607 id: tile.toString(),
46608 extent: geoExtent$$1(
46609 projection.invert([x, y + ts]),
46610 projection.invert([x + ts, y]))
46614 lodash.filter(inflight, function(v, i) {
46615 var wanted = lodash.find(tiles, function(tile) {
46616 return i === tile.id;
46618 if (!wanted) delete inflight[i];
46620 }).map(abortRequest$1);
46622 tiles.forEach(function(tile) {
46625 if (loadedTiles[id] || inflight[id]) return;
46627 if (lodash.isEmpty(inflight)) {
46628 dispatch$3.call('loading');
46631 inflight[id] = that.loadFromAPI(
46632 '/api/0.6/map?bbox=' + tile.extent.toParam(),
46633 function(err, parsed) {
46634 delete inflight[id];
46636 loadedTiles[id] = true;
46640 callback(err, lodash.extend({ data: parsed }, tile));
46643 if (lodash.isEmpty(inflight)) {
46644 dispatch$3.call('loaded');
46652 switch: function(options) {
46653 urlroot = options.urlroot;
46655 oauth.options(lodash.extend({
46657 loading: authLoading,
46660 dispatch$3.call('change');
46666 toggle: function(_) {
46672 loadedTiles: function(_) {
46673 if (!arguments.length) return loadedTiles;
46679 logout: function() {
46680 userDetails = undefined;
46682 dispatch$3.call('change');
46687 authenticate: function(callback) {
46688 userDetails = undefined;
46689 function done(err, res) {
46690 rateLimitError = undefined;
46691 dispatch$3.call('change');
46692 if (callback) callback(err, res);
46694 return oauth.authenticate(done);
46698 var endpoint$1 = 'https://taginfo.openstreetmap.org/api/4/';
46699 var taginfoCache = {};
46701 point: 'count_nodes',
46702 vertex: 'count_nodes',
46703 area: 'count_ways',
46706 var tag_sort_members = {
46707 point: 'count_node_members',
46708 vertex: 'count_node_members',
46709 area: 'count_way_members',
46710 line: 'count_way_members',
46711 relation: 'count_relation_members'
46713 var tag_filters = {
46719 var tag_members_fractions = {
46720 point: 'count_node_members_fraction',
46721 vertex: 'count_node_members_fraction',
46722 area: 'count_way_members_fraction',
46723 line: 'count_way_members_fraction',
46724 relation: 'count_relation_members_fraction'
46728 function sets(parameters, n, o) {
46729 if (parameters.geometry && o[parameters.geometry]) {
46730 parameters[n] = o[parameters.geometry];
46736 function setFilter(parameters) {
46737 return sets(parameters, 'filter', tag_filters);
46741 function setSort(parameters) {
46742 return sets(parameters, 'sortname', tag_sorts);
46746 function setSortMembers(parameters) {
46747 return sets(parameters, 'sortname', tag_sort_members);
46751 function clean(parameters) {
46752 return lodash.omit(parameters, 'geometry', 'debounce');
46756 function filterKeys(type) {
46757 var count_type = type ? 'count_' + type : 'count_all';
46758 return function(d) {
46759 return parseFloat(d[count_type]) > 2500 || d.in_wiki;
46764 function filterMultikeys(prefix) {
46765 return function(d) {
46766 // d.key begins with prefix, and d.key contains no additional ':'s
46767 var re = new RegExp('^' + prefix + '(.*)$');
46768 var matches = d.key.match(re) || [];
46769 return (matches.length === 2 && matches[1].indexOf(':') === -1);
46774 function filterValues(allowUpperCase) {
46775 return function(d) {
46776 if (d.value.match(/[;,]/) !== null) return false; // exclude some punctuation
46777 if (!allowUpperCase && d.value.match(/[A-Z*]/) !== null) return false; // exclude uppercase letters
46778 return parseFloat(d.fraction) > 0.0 || d.in_wiki;
46783 function filterRoles(geometry) {
46784 return function(d) {
46785 if (d.role === '') return false; // exclude empty role
46786 if (d.role.match(/[A-Z*;,]/) !== null) return false; // exclude uppercase letters and some punctuation
46787 return parseFloat(d[tag_members_fractions[geometry]]) > 0.0;
46792 function valKey(d) {
46800 function valKeyDescription(d) {
46803 title: d.description || d.value
46808 function roleKey(d) {
46816 // sort keys with ':' lower than keys without ':'
46817 function sortKeys(a, b) {
46818 return (a.key.indexOf(':') === -1 && b.key.indexOf(':') !== -1) ? -1
46819 : (a.key.indexOf(':') !== -1 && b.key.indexOf(':') === -1) ? 1
46824 var debounced = lodash.debounce(json, 100, true);
46827 function request$1(url, debounce, callback) {
46828 if (taginfoCache[url]) {
46829 callback(null, taginfoCache[url]);
46830 } else if (debounce) {
46831 debounced(url, done);
46836 function done(err, data) {
46838 taginfoCache[url] = data;
46840 callback(err, data);
46845 var serviceTaginfo = {
46847 init: function() { taginfoCache = {}; },
46848 reset: function() { taginfoCache = {}; },
46851 keys: function(parameters, callback) {
46852 var debounce = parameters.debounce;
46853 parameters = clean(setSort(parameters));
46854 request$1(endpoint$1 + 'keys/all?' +
46855 utilQsString(lodash.extend({
46857 sortname: 'count_all',
46860 }, parameters)), debounce, function(err, d) {
46864 var f = filterKeys(parameters.filter);
46865 callback(null, d.data.filter(f).sort(sortKeys).map(valKey));
46872 multikeys: function(parameters, callback) {
46873 var debounce = parameters.debounce;
46874 parameters = clean(setSort(parameters));
46875 var prefix = parameters.query;
46876 request$1(endpoint$1 + 'keys/all?' +
46877 utilQsString(lodash.extend({
46879 sortname: 'count_all',
46882 }, parameters)), debounce, function(err, d) {
46886 var f = filterMultikeys(prefix);
46887 callback(null, d.data.filter(f).map(valKey));
46894 values: function(parameters, callback) {
46895 var debounce = parameters.debounce;
46896 parameters = clean(setSort(setFilter(parameters)));
46897 request$1(endpoint$1 + 'key/values?' +
46898 utilQsString(lodash.extend({
46900 sortname: 'count_all',
46903 }, parameters)), debounce, function(err, d) {
46907 // In most cases we prefer taginfo value results with lowercase letters.
46908 // A few OSM keys expect values to contain uppercase values (see #3377).
46909 // This is not an exhaustive list (e.g. `name` also has uppercase values)
46910 // but these are the fields where taginfo value lookup is most useful.
46911 var re = /network|taxon|genus|species/;
46912 var allowUpperCase = (parameters.key.match(re) !== null);
46913 var f = filterValues(allowUpperCase);
46914 callback(null, d.data.filter(f).map(valKeyDescription));
46921 roles: function(parameters, callback) {
46922 var debounce = parameters.debounce;
46923 var geometry = parameters.geometry;
46924 parameters = clean(setSortMembers(parameters));
46925 request$1(endpoint$1 + 'relation/roles?' +
46926 utilQsString(lodash.extend({
46928 sortname: 'count_all_members',
46931 }, parameters)), debounce, function(err, d) {
46935 var f = filterRoles(geometry);
46936 callback(null, d.data.filter(f).map(roleKey));
46943 docs: function(parameters, callback) {
46944 var debounce = parameters.debounce;
46945 parameters = clean(setSort(parameters));
46947 var path$$1 = 'key/wiki_pages?';
46948 if (parameters.value) path$$1 = 'tag/wiki_pages?';
46949 else if (parameters.rtype) path$$1 = 'relation/wiki_pages?';
46951 request$1(endpoint$1 + path$$1 + utilQsString(parameters), debounce, function(err, d) {
46955 callback(null, d.data);
46961 endpoint: function(_) {
46962 if (!arguments.length) return endpoint$1;
46969 var jsonpCache = {};
46970 window.jsonpCache = jsonpCache;
46972 function jsonpRequest(url, callback) {
46974 if (window.JSONP_FIX) {
46975 if (window.JSONP_DELAY === 0) {
46976 callback(window.JSONP_FIX);
46978 setTimeout(function() {
46979 callback(window.JSONP_FIX);
46980 }, window.JSONP_DELAY || 0);
46986 var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
46988 while (++i < 15) c += chars.charAt(Math.floor(Math.random() * 52));
46992 function create(url) {
46993 var e = url.match(/callback=(\w+)/),
46994 c = e ? e[1] : rand();
46995 jsonpCache[c] = function(data) {
46997 delete jsonpCache[c];
47000 return 'jsonpCache.' + c;
47003 var cb = create(url),
47004 script = select('head')
47006 .attr('type', 'text/javascript')
47007 .attr('src', url.replace(/(\{|%7B)callback(\}|%7D)/, cb));
47010 var endpoint$2 = 'https://www.wikidata.org/w/api.php?';
47012 var serviceWikidata = {
47014 init: function() {},
47015 reset: function() {},
47018 // Given a Wikipedia language and article title, return an array of
47019 // corresponding Wikidata entities.
47020 itemsByTitle: function(lang, title, callback) {
47026 lang = lang || 'en';
47027 jsonpRequest(endpoint$2 + utilQsString({
47028 action: 'wbgetentities',
47030 sites: lang.replace(/-/g, '_') + 'wiki',
47032 languages: 'en', // shrink response by filtering to one language
47033 callback: '{callback}'
47034 }), function(data) {
47035 if (!data || data.error) {
47038 callback(title, data.entities || {});
47045 var endpoint$3 = 'https://en.wikipedia.org/w/api.php?';
47047 var serviceWikipedia = {
47049 init: function() {},
47050 reset: function() {},
47053 search: function(lang, query, callback) {
47059 lang = lang || 'en';
47060 jsonpRequest(endpoint$3.replace('en', lang) +
47065 srinfo: 'suggestion',
47067 callback: '{callback}',
47069 }), function(data) {
47070 if (!data || !data.query || !data.query.search || data.error) {
47073 var results = data.query.search.map(function(d) { return d.title; });
47074 callback(query, results);
47081 suggestions: function(lang, query, callback) {
47087 lang = lang || 'en';
47088 jsonpRequest(endpoint$3.replace('en', lang) +
47090 action: 'opensearch',
47094 callback: '{callback}',
47096 }), function(data) {
47097 if (!data || data.error) {
47100 callback(data[0], data[1] || []);
47107 translations: function(lang, title, callback) {
47113 jsonpRequest(endpoint$3.replace('en', lang) +
47118 callback: '{callback}',
47121 }), function(data) {
47122 if (!data || !data.query || !data.query.pages || data.error) {
47125 var list = data.query.pages[Object.keys(data.query.pages)[0]],
47127 if (list && list.langlinks) {
47128 list.langlinks.forEach(function(d) {
47129 translations[d.lang] = d['*'];
47132 callback(translations);
47141 mapillary: serviceMapillary,
47142 nominatim: serviceNominatim,
47144 taginfo: serviceTaginfo,
47145 wikidata: serviceWikidata,
47146 wikipedia: serviceWikipedia
47149 function svgMapillaryImages(projection, context, dispatch$$1) {
47150 var throttledRedraw = lodash.throttle(function () { dispatch$$1.call('change'); }, 1000),
47152 minViewfieldZoom = 17,
47153 layer = select(null),
47158 if (svgMapillaryImages.initialized) return; // run once
47159 svgMapillaryImages.enabled = false;
47160 svgMapillaryImages.initialized = true;
47164 function getMapillary() {
47165 if (services.mapillary && !_mapillary) {
47166 _mapillary = services.mapillary;
47167 _mapillary.event.on('loadedImages', throttledRedraw);
47168 } else if (!services.mapillary && _mapillary) {
47176 function showLayer() {
47177 var mapillary = getMapillary();
47178 if (!mapillary) return;
47180 mapillary.loadViewer(context);
47184 .style('opacity', 0)
47187 .style('opacity', 1)
47188 .on('end', function () { dispatch$$1.call('change'); });
47192 function hideLayer() {
47193 var mapillary = getMapillary();
47195 mapillary.hideViewer();
47198 throttledRedraw.cancel();
47203 .style('opacity', 0)
47204 .on('end', editOff);
47208 function editOn() {
47209 layer.style('display', 'block');
47213 function editOff() {
47214 layer.selectAll('.viewfield-group').remove();
47215 layer.style('display', 'none');
47219 function click(d) {
47220 var mapillary = getMapillary();
47221 if (!mapillary) return;
47223 context.map().centerEase(d.loc);
47226 .selectedImage(d.key, true)
47227 .updateViewer(d.key, context)
47232 function transform(d) {
47233 var t = svgPointTransform(projection)(d);
47234 if (d.ca) t += ' rotate(' + Math.floor(d.ca) + ',0,0)';
47239 function update() {
47240 var mapillary = getMapillary(),
47241 data = (mapillary ? mapillary.images(projection) : []),
47242 imageKey = mapillary ? mapillary.selectedImage() : null;
47244 var markers = layer.selectAll('.viewfield-group')
47245 .data(data, function(d) { return d.key; });
47250 var enter = markers.enter()
47252 .attr('class', 'viewfield-group')
47253 .classed('selected', function(d) { return d.key === imageKey; })
47254 .on('click', click);
47258 .attr('transform', transform);
47261 var viewfields = markers.selectAll('.viewfield')
47262 .data(~~context.map().zoom() >= minViewfieldZoom ? [0] : []);
47269 .attr('class', 'viewfield')
47270 .attr('transform', 'scale(1.5,1.5),translate(-8, -13)')
47271 .attr('d', 'M 6,9 C 8,8.4 8,8.4 10,9 L 16,-2 C 12,-5 4,-5 0,-2 z');
47273 markers.selectAll('circle')
47283 function drawImages(selection$$1) {
47284 var enabled = svgMapillaryImages.enabled,
47285 mapillary = getMapillary();
47287 layer = selection$$1.selectAll('.layer-mapillary-images')
47288 .data(mapillary ? [0] : []);
47293 layer = layer.enter()
47295 .attr('class', 'layer-mapillary-images')
47296 .style('display', enabled ? 'block' : 'none')
47300 if (mapillary && ~~context.map().zoom() >= minZoom) {
47303 mapillary.loadImages(projection);
47311 drawImages.enabled = function(_) {
47312 if (!arguments.length) return svgMapillaryImages.enabled;
47313 svgMapillaryImages.enabled = _;
47314 if (svgMapillaryImages.enabled) {
47319 dispatch$$1.call('change');
47324 drawImages.supported = function() {
47325 return !!getMapillary();
47333 function svgMapillarySigns(projection, context, dispatch$$1) {
47334 var throttledRedraw = lodash.throttle(function () { dispatch$$1.call('change'); }, 1000),
47336 layer = select(null),
47341 if (svgMapillarySigns.initialized) return; // run once
47342 svgMapillarySigns.enabled = false;
47343 svgMapillarySigns.initialized = true;
47347 function getMapillary() {
47348 if (services.mapillary && !_mapillary) {
47349 _mapillary = services.mapillary;
47350 _mapillary.event.on('loadedSigns', throttledRedraw);
47351 } else if (!services.mapillary && _mapillary) {
47358 function showLayer() {
47363 function hideLayer() {
47364 throttledRedraw.cancel();
47369 function editOn() {
47370 layer.style('display', 'block');
47374 function editOff() {
47375 layer.selectAll('.icon-sign').remove();
47376 layer.style('display', 'none');
47380 function click(d) {
47381 var mapillary = getMapillary();
47382 if (!mapillary) return;
47384 context.map().centerEase(d.loc);
47387 .selectedImage(d.key, true)
47388 .updateViewer(d.key, context)
47393 function update() {
47394 var mapillary = getMapillary(),
47395 data = (mapillary ? mapillary.signs(projection) : []),
47396 imageKey = mapillary ? mapillary.selectedImage() : null;
47398 var signs = layer.selectAll('.icon-sign')
47399 .data(data, function(d) { return d.key; });
47404 var enter = signs.enter()
47405 .append('foreignObject')
47406 .attr('class', 'icon-sign')
47407 .attr('width', '32px') // for Firefox
47408 .attr('height', '32px') // for Firefox
47409 .classed('selected', function(d) { return d.key === imageKey; })
47410 .on('click', click);
47413 .append('xhtml:body')
47414 .attr('class', 'icon-sign-body')
47415 .html(mapillary.signHTML);
47419 .attr('x', function(d) { return projection(d.loc)[0] - 16; }) // offset by -16px to
47420 .attr('y', function(d) { return projection(d.loc)[1] - 16; }); // center signs on loc
47424 function drawSigns(selection$$1) {
47425 var enabled = svgMapillarySigns.enabled,
47426 mapillary = getMapillary();
47428 layer = selection$$1.selectAll('.layer-mapillary-signs')
47429 .data(mapillary ? [0] : []);
47434 layer = layer.enter()
47436 .attr('class', 'layer-mapillary-signs')
47437 .style('display', enabled ? 'block' : 'none')
47441 if (mapillary && ~~context.map().zoom() >= minZoom) {
47444 mapillary.loadSigns(context, projection);
47452 drawSigns.enabled = function(_) {
47453 if (!arguments.length) return svgMapillarySigns.enabled;
47454 svgMapillarySigns.enabled = _;
47455 if (svgMapillarySigns.enabled) {
47460 dispatch$$1.call('change');
47465 drawSigns.supported = function() {
47466 var mapillary = getMapillary();
47467 return (mapillary && mapillary.signsSupported());
47475 function svgOsm() {
47476 return function drawOsm(selection) {
47477 var layers = selection.selectAll('.layer-osm')
47478 .data(['areas', 'lines', 'hit', 'halo', 'label']);
47482 .attr('class', function(d) { return 'layer-osm layer-' + d; });
47486 function svgLayers(projection, context) {
47487 var dispatch$$1 = dispatch('change'),
47488 svg = select(null),
47490 { id: 'osm', layer: svgOsm(projection, context, dispatch$$1) },
47491 { id: 'gpx', layer: svgGpx(projection, context, dispatch$$1) },
47492 { id: 'mapillary-images', layer: svgMapillaryImages(projection, context, dispatch$$1) },
47493 { id: 'mapillary-signs', layer: svgMapillarySigns(projection, context, dispatch$$1) },
47494 { id: 'debug', layer: svgDebug(projection, context, dispatch$$1) }
47498 function drawLayers(selection$$1) {
47499 svg = selection$$1.selectAll('.surface')
47504 .attr('class', 'surface')
47507 var defs = svg.selectAll('.surface-defs')
47512 .attr('class', 'surface-defs');
47514 var groups = svg.selectAll('.data-layer')
47522 .attr('class', function(d) { return 'data-layer data-layer-' + d.id; })
47524 .each(function(d) { select(this).call(d.layer); });
47528 drawLayers.all = function() {
47533 drawLayers.layer = function(id) {
47534 var obj = lodash.find(layers, function(o) {return o.id === id;});
47535 return obj && obj.layer;
47539 drawLayers.only = function(what) {
47540 var arr = [].concat(what);
47541 drawLayers.remove(lodash.difference(lodash.map(layers, 'id'), arr));
47546 drawLayers.remove = function(what) {
47547 var arr = [].concat(what);
47548 arr.forEach(function(id) {
47549 layers = lodash.reject(layers, function(o) {return o.id === id;});
47551 dispatch$$1.call('change');
47556 drawLayers.add = function(what) {
47557 var arr = [].concat(what);
47558 arr.forEach(function(obj) {
47559 if ('id' in obj && 'layer' in obj) {
47563 dispatch$$1.call('change');
47568 drawLayers.dimensions = function(_) {
47569 if (!arguments.length) return utilGetDimensions(svg);
47570 utilSetDimensions(svg, _);
47575 return utilRebind(drawLayers, dispatch$$1, 'on');
47578 function svgLines$$1(projection) {
47579 var detected = utilDetect();
47581 var highway_stack = {
47596 function waystack(a, b) {
47597 var as = 0, bs = 0;
47598 if (a.tags.highway) { as -= highway_stack[a.tags.highway]; }
47599 if (b.tags.highway) { bs -= highway_stack[b.tags.highway]; }
47604 return function drawLines(selection$$1, graph, entities, filter) {
47605 var ways = [], pathdata = {}, onewaydata = {},
47606 getPath = svgPath(projection, graph);
47608 for (var i = 0; i < entities.length; i++) {
47609 var entity = entities[i],
47610 outer = osmSimpleMultipolygonOuterMember(entity, graph);
47612 ways.push(entity.mergeTags(outer.tags));
47613 } else if (entity.geometry(graph) === 'line') {
47618 ways = ways.filter(getPath);
47620 pathdata = lodash.groupBy(ways, function(way) { return way.layer(); });
47622 lodash.forOwn(pathdata, function(v, k) {
47623 onewaydata[k] = lodash(v)
47624 .filter(function(d) { return d.isOneWay(); })
47625 .map(svgOneWaySegments(projection, graph, 35))
47630 var layer = selection$$1.selectAll('.layer-lines');
47632 var layergroup = layer
47633 .selectAll('g.layergroup')
47634 .data(range(-10, 11));
47636 layergroup = layergroup.enter()
47638 .attr('class', function(d) { return 'layergroup layer' + String(d); })
47639 .merge(layergroup);
47642 var linegroup = layergroup
47643 .selectAll('g.linegroup')
47644 .data(['shadow', 'casing', 'stroke']);
47646 linegroup = linegroup.enter()
47648 .attr('class', function(d) { return 'linegroup line-' + d; })
47652 var lines = linegroup
47656 function() { return pathdata[this.parentNode.__data__] || []; },
47663 // Optimization: call simple TagClasses only on enter selection. This
47664 // works because osmEntity.key is defined to include the entity v attribute.
47667 .attr('class', function(d) { return 'way line ' + this.parentNode.__data__ + ' ' + d.id; })
47668 .call(svgTagClasses())
47671 .attr('d', getPath)
47672 .call(svgTagClasses().tags(svgRelationMemberTags(graph)));
47675 var onewaygroup = layergroup
47676 .selectAll('g.onewaygroup')
47679 onewaygroup = onewaygroup.enter()
47681 .attr('class', 'onewaygroup')
47682 .merge(onewaygroup);
47685 var oneways = onewaygroup
47689 function() { return onewaydata[this.parentNode.__data__] || []; },
47690 function(d) { return [d.id, d.index]; }
47696 oneways = oneways.enter()
47698 .attr('class', 'oneway')
47699 .attr('marker-mid', 'url(#oneway-marker)')
47701 .attr('d', function(d) { return d.d; });
47704 oneways.each(function() { this.parentNode.insertBefore(this, this); });
47709 function svgMidpoints$$1(projection, context) {
47711 return function drawMidpoints(selection, graph, entities, filter, extent) {
47712 var poly = extent.polygon(),
47715 for (var i = 0; i < entities.length; i++) {
47716 var entity = entities[i];
47718 if (entity.type !== 'way')
47720 if (!filter(entity))
47722 if (context.selectedIDs().indexOf(entity.id) < 0)
47725 var nodes = graph.childNodes(entity);
47726 for (var j = 0; j < nodes.length - 1; j++) {
47730 id = [a.id, b.id].sort().join('-');
47732 if (midpoints[id]) {
47733 midpoints[id].parents.push(entity);
47735 if (geoEuclideanDistance(projection(a.loc), projection(b.loc)) > 40) {
47736 var point = geoInterp(a.loc, b.loc, 0.5),
47739 if (extent.intersects(point)) {
47742 for (var k = 0; k < 4; k++) {
47743 point = geoLineIntersection([a.loc, b.loc], [poly[k], poly[k + 1]]);
47745 geoEuclideanDistance(projection(a.loc), projection(point)) > 20 &&
47746 geoEuclideanDistance(projection(b.loc), projection(point)) > 20)
47759 edge: [a.id, b.id],
47769 function midpointFilter(d) {
47770 if (midpoints[d.id])
47773 for (var i = 0; i < d.parents.length; i++) {
47774 if (filter(d.parents[i])) {
47783 var layer = selection.selectAll('.layer-hit');
47786 .selectAll('g.midpoint')
47787 .filter(midpointFilter)
47788 .data(lodash.values(midpoints), function(d) { return d.id; });
47793 var enter = groups.enter()
47794 .insert('g', ':first-child')
47795 .attr('class', 'midpoint');
47797 enter.append('polygon')
47798 .attr('points', '-6,8 10,0 -6,-8')
47799 .attr('class', 'shadow');
47801 enter.append('polygon')
47802 .attr('points', '-3,4 5,0 -3,-4')
47803 .attr('class', 'fill');
47807 .attr('transform', function(d) {
47808 var translate = svgPointTransform(projection),
47809 a = graph.entity(d.edge[0]),
47810 b = graph.entity(d.edge[1]),
47811 angleVal = Math.round(geoAngle(a, b, projection) * (180 / Math.PI));
47812 return translate(d) + ' rotate(' + angleVal + ')';
47814 .call(svgTagClasses().tags(
47815 function(d) { return d.parents[0].tags; }
47818 // Propagate data bindings.
47819 groups.select('polygon.shadow');
47820 groups.select('polygon.fill');
47825 function svgOneWaySegments(projection, graph, dt) {
47826 return function(entity) {
47832 clip = identity$8().clipExtent(projection.clipExtent()).stream,
47833 coordinates = graph.childNodes(entity).map(function(n) {
47837 if (entity.tags.oneway === '-1') coordinates.reverse();
47840 type: 'LineString',
47841 coordinates: coordinates
47842 }, projection.stream(clip({
47843 lineStart: function() {},
47844 lineEnd: function() {
47847 point: function(x, y) {
47851 var span = geoEuclideanDistance(a, b) - offset;
47854 var angle = Math.atan2(b[1] - a[1], b[0] - a[0]),
47855 dx = dt * Math.cos(angle),
47856 dy = dt * Math.sin(angle),
47857 p = [a[0] + offset * Math.cos(angle),
47858 a[1] + offset * Math.sin(angle)];
47860 var segment = 'M' + a[0] + ',' + a[1] +
47861 'L' + p[0] + ',' + p[1];
47863 for (span -= dt; span >= 0; span -= dt) {
47866 segment += 'L' + p[0] + ',' + p[1];
47869 segment += 'L' + b[0] + ',' + b[1];
47870 segments.push({id: entity.id, index: i, d: segment});
47885 function svgPath(projection, graph, isArea) {
47887 // Explanation of magic numbers:
47888 // "padding" here allows space for strokes to extend beyond the viewport,
47889 // so that the stroke isn't drawn along the edge of the viewport when
47890 // the shape is clipped.
47892 // When drawing lines, pad viewport by 5px.
47893 // When drawing areas, pad viewport by 65px in each direction to allow
47894 // for 60px area fill stroke (see ".fill-partial path.fill" css rule)
47897 padding = isArea ? 65 : 5,
47898 viewport = projection.clipExtent(),
47900 [viewport[0][0] - padding, viewport[0][1] - padding],
47901 [viewport[1][0] + padding, viewport[1][1] + padding]
47903 clip = identity$8().clipExtent(paddedExtent).stream,
47904 project = projection.stream,
47905 path$$1 = index$5()
47906 .projection({stream: function(output) { return project(clip(output)); }});
47908 return function(entity) {
47909 if (entity.id in cache) {
47910 return cache[entity.id];
47912 return cache[entity.id] = path$$1(entity.asGeoJSON(graph));
47917 function svgPoints$$1(projection, context) {
47919 function markerPath(selection, klass) {
47921 .attr('class', klass)
47922 .attr('transform', 'translate(-8, -23)')
47923 .attr('d', 'M 17,8 C 17,13 11,21 8.5,23.5 C 6,21 0,13 0,8 C 0,4 4,-0.5 8.5,-0.5 C 13,-0.5 17,4 17,8 z');
47926 function sortY(a, b) {
47927 return b.loc[1] - a.loc[1];
47931 return function drawPoints(selection, graph, entities, filter) {
47932 var wireframe = context.surface().classed('fill-wireframe'),
47933 points = wireframe ? [] : lodash.filter(entities, function(e) {
47934 return e.geometry(graph) === 'point';
47937 points.sort(sortY);
47939 var layer = selection.selectAll('.layer-hit');
47941 var groups = layer.selectAll('g.point')
47943 .data(points, osmEntity$$1.key);
47948 var enter = groups.enter()
47950 .attr('class', function(d) { return 'node point ' + d.id; })
47953 enter.append('path')
47954 .call(markerPath, 'shadow');
47956 enter.append('path')
47957 .call(markerPath, 'stroke');
47959 enter.append('use')
47960 .attr('transform', 'translate(-6, -20)')
47961 .attr('class', 'icon')
47962 .attr('width', '12px')
47963 .attr('height', '12px');
47967 .attr('transform', svgPointTransform(projection))
47968 .call(svgTagClasses());
47970 // Selecting the following implicitly
47971 // sets the data (point entity) on the element
47972 groups.select('.shadow');
47973 groups.select('.stroke');
47974 groups.select('.icon')
47975 .attr('xlink:href', function(entity) {
47976 var preset = context.presets().match(entity, graph);
47977 return (preset && preset.icon) ? '#' + preset.icon + '-12' : '';
47982 function svgRelationMemberTags(graph) {
47983 return function(entity) {
47984 var tags = entity.tags;
47985 graph.parentRelations(entity).forEach(function(relation) {
47986 var type = relation.tags.type;
47987 if (type === 'multipolygon' || type === 'boundary') {
47988 tags = lodash.extend({}, relation.tags, tags);
47995 function svgTagClasses() {
47997 'building', 'highway', 'railway', 'waterway', 'aeroway',
47998 'motorway', 'boundary', 'power', 'amenity', 'natural', 'landuse',
48002 'proposed', 'construction', 'disused', 'abandoned', 'dismantled',
48003 'razed', 'demolished', 'obliterated'
48006 'oneway', 'bridge', 'tunnel', 'embankment', 'cutting', 'barrier',
48007 'surface', 'tracktype', 'crossing'
48009 tagClassRe = /^tag-/,
48010 tags = function(entity) { return entity.tags; };
48013 var tagClasses = function(selection$$1) {
48014 selection$$1.each(function tagClassesEach(entity) {
48015 var value = this.className,
48016 classes, primary, status;
48018 if (value.baseVal !== undefined) value = value.baseVal;
48020 classes = value.trim().split(/\s+/).filter(function(name) {
48021 return name.length && !tagClassRe.test(name);
48024 var t = tags(entity), i, k, v;
48026 // pick at most one primary classification tag..
48027 for (i = 0; i < primaries.length; i++) {
48030 if (!v || v === 'no') continue;
48033 if (statuses.indexOf(v) !== -1) { // e.g. `railway=abandoned`
48035 classes += ' tag-' + k;
48037 classes += ' tag-' + k + ' tag-' + k + '-' + v;
48043 // add at most one status tag, only if relates to primary tag..
48045 for (i = 0; i < statuses.length; i++) {
48048 if (!v || v === 'no') continue;
48050 if (v === 'yes') { // e.g. `railway=rail + abandoned=yes`
48053 else if (primary && primary === v) { // e.g. `railway=rail + abandoned=railway`
48055 } else if (!primary && primaries.indexOf(v) !== -1) { // e.g. `abandoned=railway`
48058 classes += ' tag-' + v;
48059 } // else ignore e.g. `highway=path + abandoned=railway`
48066 classes += ' tag-status tag-status-' + status;
48069 // add any secondary (structure) tags
48070 for (i = 0; i < secondaries.length; i++) {
48071 k = secondaries[i];
48073 if (!v || v === 'no') continue;
48074 classes += ' tag-' + k + ' tag-' + k + '-' + v;
48077 // For highways, look for surface tagging..
48078 if (primary === 'highway') {
48079 var paved = (t.highway !== 'track');
48082 if (k in osmPavedTags) {
48083 paved = !!osmPavedTags[k][v];
48088 classes += ' tag-unpaved';
48092 classes = classes.trim();
48094 if (classes !== value) {
48095 select(this).attr('class', classes);
48101 tagClasses.tags = function(_) {
48102 if (!arguments.length) return tags;
48110 function svgTurns(projection) {
48112 return function drawTurns(selection, graph, turns) {
48114 function key(turn) {
48115 return [turn.from.node + turn.via.node + turn.to.node].join('-');
48118 function icon(turn) {
48119 var u = turn.u ? '-u' : '';
48120 if (!turn.restriction)
48121 return '#turn-yes' + u;
48122 var restriction = graph.entity(turn.restriction).tags.restriction;
48124 (!turn.indirect_restriction && /^only_/.test(restriction) ? 'only' : 'no') + u;
48127 var groups = selection.selectAll('.layer-hit').selectAll('g.turn')
48134 var enter = groups.enter()
48136 .attr('class', 'turn');
48139 .filter(function (turn) { return !turn.u; });
48141 nEnter.append('rect')
48142 .attr('transform', 'translate(-22, -12)')
48143 .attr('width', '44')
48144 .attr('height', '24');
48146 nEnter.append('use')
48147 .attr('transform', 'translate(-22, -12)')
48148 .attr('width', '44')
48149 .attr('height', '24');
48153 .filter(function (turn) { return turn.u; });
48155 uEnter.append('circle')
48158 uEnter.append('use')
48159 .attr('transform', 'translate(-16, -16)')
48160 .attr('width', '32')
48161 .attr('height', '32');
48168 .attr('transform', function (turn) {
48169 var v = graph.entity(turn.via.node),
48170 t = graph.entity(turn.to.node),
48171 a = geoAngle(v, t, projection),
48172 p = projection(v.loc),
48173 r = turn.u ? 0 : 60;
48175 return 'translate(' + (r * Math.cos(a) + p[0]) + ',' + (r * Math.sin(a) + p[1]) + ') ' +
48176 'rotate(' + a * 180 / Math.PI + ')';
48179 groups.select('use')
48180 .attr('xlink:href', icon);
48182 groups.select('rect');
48183 groups.select('circle');
48189 function svgVertices$$1(projection, context) {
48191 // z16-, z17, z18+, tagged
48192 shadow: [6, 7.5, 7.5, 11.5],
48193 stroke: [2.5, 3.5, 3.5, 7],
48194 fill: [1, 1.5, 1.5, 1.5]
48199 function siblingAndChildVertices(ids, graph, extent$$1) {
48202 function addChildVertices(entity) {
48203 if (!context.features().isHiddenFeature(entity, graph, entity.geometry(graph))) {
48205 if (entity.type === 'way') {
48206 for (i = 0; i < entity.nodes.length; i++) {
48207 addChildVertices(graph.entity(entity.nodes[i]));
48209 } else if (entity.type === 'relation') {
48210 for (i = 0; i < entity.members.length; i++) {
48211 var member = context.hasEntity(entity.members[i].id);
48213 addChildVertices(member);
48216 } else if (entity.intersects(extent$$1, graph)) {
48217 vertices[entity.id] = entity;
48222 ids.forEach(function(id) {
48223 var entity = context.hasEntity(id);
48224 if (entity && entity.type === 'node') {
48225 vertices[entity.id] = entity;
48226 context.graph().parentWays(entity).forEach(function(entity) {
48227 addChildVertices(entity);
48229 } else if (entity) {
48230 addChildVertices(entity);
48238 function draw(selection$$1, vertices, klass, graph, zoom$$1) {
48240 function icon(entity) {
48241 if (entity.id in icons) return icons[entity.id];
48243 entity.hasInterestingTags() &&
48244 context.presets().match(entity, graph).icon;
48245 return icons[entity.id];
48248 function setClass(klass) {
48249 return function(entity) {
48250 this.setAttribute('class', 'node vertex ' + klass + ' ' + entity.id);
48254 function setAttributes(selection$$1) {
48255 ['shadow','stroke','fill'].forEach(function(klass) {
48256 var rads = radiuses[klass];
48257 selection$$1.selectAll('.' + klass)
48258 .each(function(entity) {
48259 var i = z && icon(entity),
48261 r = rads[i ? 3 : z];
48262 this.setAttribute('cx', c);
48263 this.setAttribute('cy', -c);
48264 this.setAttribute('r', r);
48265 if (i && klass === 'fill') {
48266 this.setAttribute('visibility', 'hidden');
48268 this.removeAttribute('visibility');
48273 selection$$1.selectAll('use')
48276 this.removeAttribute('visibility');
48278 this.setAttribute('visibility', 'hidden');
48285 z = (zoom$$1 < 17 ? 0 : zoom$$1 < 18 ? 1 : 2);
48287 var groups = selection$$1
48288 .data(vertices, osmEntity$$1.key);
48293 var enter = groups.enter()
48295 .attr('class', function(d) { return 'node vertex ' + klass + ' ' + d.id; });
48297 enter.append('circle')
48298 .each(setClass('shadow'));
48300 enter.append('circle')
48301 .each(setClass('stroke'));
48303 // Vertices with icons get a `use`.
48304 enter.filter(function(d) { return icon(d); })
48306 .attr('transform', 'translate(-6, -6)')
48307 .attr('xlink:href', function(d) { return '#' + icon(d) + '-12'; })
48308 .attr('width', '12px')
48309 .attr('height', '12px')
48310 .each(setClass('icon'));
48312 // Vertices with tags get a fill.
48313 enter.filter(function(d) { return d.hasInterestingTags(); })
48315 .each(setClass('fill'));
48319 .attr('transform', svgPointTransform(projection))
48320 .classed('shared', function(entity) { return graph.isShared(entity); })
48321 .call(setAttributes);
48325 function drawVertices(selection$$1, graph, entities, filter, extent$$1, zoom$$1) {
48326 var selected = siblingAndChildVertices(context.selectedIDs(), graph, extent$$1),
48327 wireframe = context.surface().classed('fill-wireframe'),
48330 for (var i = 0; i < entities.length; i++) {
48331 var entity = entities[i],
48332 geometry = entity.geometry(graph);
48334 if (wireframe && geometry === 'point') {
48335 vertices.push(entity);
48339 if (geometry !== 'vertex')
48342 if (entity.id in selected ||
48343 entity.hasInterestingTags() ||
48344 entity.isIntersection(graph)) {
48345 vertices.push(entity);
48349 var layer = selection$$1.selectAll('.layer-hit');
48350 layer.selectAll('g.vertex.vertex-persistent')
48352 .call(draw, vertices, 'vertex-persistent', graph, zoom$$1);
48354 drawHover(selection$$1, graph, extent$$1, zoom$$1);
48358 function drawHover(selection$$1, graph, extent$$1, zoom$$1) {
48359 var hovered = hover ? siblingAndChildVertices([hover.id], graph, extent$$1) : {};
48360 var layer = selection$$1.selectAll('.layer-hit');
48362 layer.selectAll('g.vertex.vertex-hover')
48363 .call(draw, values(hovered), 'vertex-hover', graph, zoom$$1);
48367 drawVertices.drawHover = function(selection$$1, graph, target, extent$$1, zoom$$1) {
48368 if (target === hover) return;
48370 drawHover(selection$$1, graph, extent$$1, zoom$$1);
48373 return drawVertices;
48376 function behaviorEdit(context) {
48380 .minzoom(context.minEditableZoom());
48384 edit.off = function() {
48394 The hover behavior adds the `.hover` class on mouseover to all elements to which
48395 the identical datum is bound, and removes it on mouseout.
48397 The :hover pseudo-class is insufficient for iD's purposes because a datum's visual
48398 representation may consist of several elements scattered throughout the DOM hierarchy.
48399 Only one of these elements can have the :hover pseudo-class, but all of them will
48400 have the .hover class.
48402 function behaviorHover() {
48403 var dispatch$$1 = dispatch('hover'),
48404 selection$$1 = select(null),
48410 function keydown() {
48411 if (altDisables && event.keyCode === d3keybinding.modifierCodes.alt) {
48412 dispatch$$1.call('hover', this, null);
48413 selection$$1.selectAll('.hover')
48414 .classed('hover-suppressed', true)
48415 .classed('hover', false);
48421 if (altDisables && event.keyCode === d3keybinding.modifierCodes.alt) {
48422 dispatch$$1.call('hover', this, target ? target.id : null);
48423 selection$$1.selectAll('.hover-suppressed')
48424 .classed('hover-suppressed', false)
48425 .classed('hover', true);
48430 var hover = function(__) {
48434 .on('mouseover.hover', mouseover)
48435 .on('mouseout.hover', mouseout)
48436 .on('mousedown.hover', mousedown);
48439 .on('keydown.hover', keydown)
48440 .on('keyup.hover', keyup);
48443 function mouseover() {
48444 if (buttonDown) return;
48445 var target = event.target;
48446 enter(target ? target.__data__ : null);
48450 function mouseout() {
48451 if (buttonDown) return;
48452 var target = event.relatedTarget;
48453 enter(target ? target.__data__ : null);
48457 function mousedown() {
48460 .on('mouseup.hover', mouseup, true);
48464 function mouseup() {
48465 buttonDown = false;
48467 .on('mouseup.hover', null, true);
48471 function enter(d) {
48472 if (d === target) return;
48475 selection$$1.selectAll('.hover')
48476 .classed('hover', false);
48477 selection$$1.selectAll('.hover-suppressed')
48478 .classed('hover-suppressed', false);
48480 if (target instanceof osmEntity$$1) {
48481 var selector$$1 = '.' + target.id;
48483 if (target.type === 'relation') {
48484 target.members.forEach(function(member) {
48485 selector$$1 += ', .' + member.id;
48489 var suppressed = altDisables && event && event.altKey;
48491 selection$$1.selectAll(selector$$1)
48492 .classed(suppressed ? 'hover-suppressed' : 'hover', true);
48494 dispatch$$1.call('hover', this, target.id);
48496 dispatch$$1.call('hover', this, null);
48503 hover.off = function(selection$$1) {
48504 selection$$1.selectAll('.hover')
48505 .classed('hover', false);
48506 selection$$1.selectAll('.hover-suppressed')
48507 .classed('hover-suppressed', false);
48510 .on('mouseover.hover', null)
48511 .on('mouseout.hover', null)
48512 .on('mousedown.hover', null);
48515 .on('keydown.hover', null)
48516 .on('keyup.hover', null);
48520 hover.altDisables = function(_) {
48521 if (!arguments.length) return altDisables;
48527 return utilRebind(hover, dispatch$$1, 'on');
48530 function behaviorTail() {
48534 tooltipSize = [0, 0],
48535 selectionSize = [0, 0];
48538 function tail(selection$$1) {
48539 if (!text$$1) return;
48542 .on('resize.tail', function() { selectionSize = utilGetDimensions(selection$$1); });
48544 container = select(document.body)
48546 .style('display', 'none')
48547 .attr('class', 'tail tooltip-inner');
48549 container.append('div')
48553 .on('mousemove.tail', mousemove)
48554 .on('mouseenter.tail', mouseenter)
48555 .on('mouseleave.tail', mouseleave);
48558 .on('mousemove.tail', mousemove);
48560 tooltipSize = utilGetDimensions(container);
48561 selectionSize = utilGetDimensions(selection$$1);
48565 container.style('display', 'block');
48566 tooltipSize = utilGetDimensions(container);
48570 function mousemove() {
48571 if (container.style('display') === 'none') show();
48572 var xoffset = ((event.clientX + tooltipSize[0] + xmargin) > selectionSize[0]) ?
48573 -tooltipSize[0] - xmargin : xmargin;
48574 container.classed('left', xoffset > 0);
48575 utilSetTransform(container, event.clientX + xoffset, event.clientY);
48579 function mouseleave() {
48580 if (event.relatedTarget !== container.node()) {
48581 container.style('display', 'none');
48586 function mouseenter() {
48587 if (event.relatedTarget !== container.node()) {
48594 tail.off = function(selection$$1) {
48595 if (!text$$1) return;
48598 .on('mousemove.tail', null)
48602 .on('mousemove.tail', null)
48603 .on('mouseenter.tail', null)
48604 .on('mouseleave.tail', null);
48607 .on('resize.tail', null);
48611 tail.text = function(_) {
48612 if (!arguments.length) return text$$1;
48621 behaviorDraw.usedTails = {};
48622 behaviorDraw.disableSpace = false;
48623 behaviorDraw.lastSpace = null;
48626 function behaviorDraw(context) {
48627 var dispatch$$1 = dispatch('move', 'click', 'clickWay',
48628 'clickNode', 'undo', 'cancel', 'finish'),
48629 keybinding = d3keybinding('draw'),
48630 hover = behaviorHover(context)
48632 .on('hover', context.ui().sidebar.hover),
48633 tail = behaviorTail(),
48634 edit = behaviorEdit(context),
48635 closeTolerance = 4,
48637 mouseLeave = false,
48639 cached = behaviorDraw;
48643 if (event.altKey) return {};
48645 if (event.type === 'keydown') {
48646 return (lastMouse && lastMouse.target.__data__) || {};
48648 return event.target.__data__ || {};
48653 function mousedown() {
48656 var p = context.container().node();
48657 return touchId !== null ? touches(p).filter(function(p) {
48658 return p.identifier === touchId;
48662 var element = select(this),
48663 touchId = event.touches ? event.changedTouches[0].identifier : null,
48667 element.on('mousemove.draw', null);
48669 select(window).on('mouseup.draw', function() {
48670 var t2 = +new Date(),
48672 dist = geoEuclideanDistance(p1, p2);
48674 element.on('mousemove.draw', mousemove);
48675 select(window).on('mouseup.draw', null);
48677 if (dist < closeTolerance || (dist < tolerance && (t2 - t1) < 500)) {
48678 // Prevent a quick second click
48679 select(window).on('click.draw-block', function() {
48680 event.stopPropagation();
48683 context.map().dblclickEnable(false);
48685 window.setTimeout(function() {
48686 context.map().dblclickEnable(true);
48687 select(window).on('click.draw-block', null);
48696 function mousemove() {
48698 dispatch$$1.call('move', this, datum());
48702 function mouseenter() {
48703 mouseLeave = false;
48707 function mouseleave() {
48714 if (d.type === 'way') {
48715 var dims = context.map().dimensions(),
48716 mouse$$1 = context.mouse(),
48718 trySnap = mouse$$1[0] > pad && mouse$$1[0] < dims[0] - pad &&
48719 mouse$$1[1] > pad && mouse$$1[1] < dims[1] - pad;
48722 var choice = geoChooseEdge(context.childNodes(d), context.mouse(), context.projection),
48723 edge = [d.nodes[choice.index - 1], d.nodes[choice.index]];
48724 dispatch$$1.call('clickWay', this, choice.loc, edge);
48726 dispatch$$1.call('click', this, context.map().mouseCoordinates());
48729 } else if (d.type === 'node') {
48730 dispatch$$1.call('clickNode', this, d);
48733 dispatch$$1.call('click', this, context.map().mouseCoordinates());
48739 var currSpace = context.mouse();
48740 if (cached.disableSpace && cached.lastSpace) {
48741 var dist = geoEuclideanDistance(cached.lastSpace, currSpace);
48742 if (dist > tolerance) {
48743 cached.disableSpace = false;
48747 if (cached.disableSpace || mouseLeave || !lastMouse) return;
48749 // user must move mouse or release space bar to allow another click
48750 cached.lastSpace = currSpace;
48751 cached.disableSpace = true;
48753 select(window).on('keyup.space-block', function() {
48754 cached.disableSpace = false;
48755 select(window).on('keyup.space-block', null);
48758 event.preventDefault();
48763 function backspace() {
48764 event.preventDefault();
48765 dispatch$$1.call('undo');
48770 event.preventDefault();
48771 dispatch$$1.call('cancel');
48776 event.preventDefault();
48777 dispatch$$1.call('finish');
48781 function draw(selection$$1) {
48782 context.install(hover);
48783 context.install(edit);
48785 if (!context.inIntro() && !cached.usedTails[tail.text()]) {
48786 context.install(tail);
48790 .on('⌫', backspace)
48794 .on('space', space)
48795 .on('⌥space', space);
48798 .on('mouseenter.draw', mouseenter)
48799 .on('mouseleave.draw', mouseleave)
48800 .on('mousedown.draw', mousedown)
48801 .on('mousemove.draw', mousemove);
48810 draw.off = function(selection$$1) {
48811 context.ui().sidebar.hover.cancel();
48812 context.uninstall(hover);
48813 context.uninstall(edit);
48815 if (!context.inIntro() && !cached.usedTails[tail.text()]) {
48816 context.uninstall(tail);
48817 cached.usedTails[tail.text()] = true;
48821 .on('mouseenter.draw', null)
48822 .on('mouseleave.draw', null)
48823 .on('mousedown.draw', null)
48824 .on('mousemove.draw', null);
48827 .on('mouseup.draw', null);
48828 // note: keyup.space-block, click.draw-block should remain
48831 .call(keybinding.off);
48835 draw.tail = function(_) {
48841 return utilRebind(draw, dispatch$$1, 'on');
48844 function behaviorAddWay(context) {
48845 var dispatch$$1 = dispatch('start', 'startFromWay', 'startFromNode'),
48846 draw = behaviorDraw(context);
48848 var addWay = function(surface) {
48849 draw.on('click', function() { dispatch$$1.apply('start', this, arguments); })
48850 .on('clickWay', function() { dispatch$$1.apply('startFromWay', this, arguments); })
48851 .on('clickNode', function() { dispatch$$1.apply('startFromNode', this, arguments); })
48852 .on('cancel', addWay.cancel)
48853 .on('finish', addWay.cancel);
48856 .dblclickEnable(false);
48858 surface.call(draw);
48862 addWay.off = function(surface) {
48863 surface.call(draw.off);
48867 addWay.cancel = function() {
48868 window.setTimeout(function() {
48869 context.map().dblclickEnable(true);
48872 context.enter(modeBrowse$$1(context));
48876 addWay.tail = function(text$$1) {
48877 draw.tail(text$$1);
48882 return utilRebind(addWay, dispatch$$1, 'on');
48885 function behaviorBreathe() {
48886 var duration = 800,
48888 selector$$1 = '.selected.shadow, .selected .shadow',
48889 selected = select(null),
48896 // This is a workaround for a bug in rollup v0.36
48897 // https://github.com/rollup/rollup/issues/984
48898 // The symbol for this default export is not used anywhere, but it
48899 // needs to be called in order to be included in the bundle.
48900 var t = transition();
48903 function ratchetyInterpolator(a, b, steps, units) {
48906 var sample = quantize$1()
48908 .range(quantize(interpolateNumber(a, b), steps));
48910 return function(t) {
48911 return String(sample(t)) + (units || '');
48916 function reset(selection$$1) {
48918 .style('stroke-opacity', null)
48919 .style('stroke-width', null)
48920 .style('fill-opacity', null)
48925 function setAnimationParams(transition$$1, fromTo) {
48926 var toFrom = (fromTo === 'from' ? 'to' : 'from');
48929 .styleTween('stroke-opacity', function(d) {
48930 return ratchetyInterpolator(
48931 params[d.id][toFrom].opacity,
48932 params[d.id][fromTo].opacity,
48936 .styleTween('stroke-width', function(d) {
48937 return ratchetyInterpolator(
48938 params[d.id][toFrom].width,
48939 params[d.id][fromTo].width,
48944 .styleTween('fill-opacity', function(d) {
48945 return ratchetyInterpolator(
48946 params[d.id][toFrom].opacity,
48947 params[d.id][fromTo].opacity,
48951 .styleTween('r', function(d) {
48952 return ratchetyInterpolator(
48953 params[d.id][toFrom].width,
48954 params[d.id][fromTo].width,
48962 function calcAnimationParams(selection$$1) {
48965 .each(function(d) {
48966 var s = select(this),
48967 tag = s.node().tagName,
48968 p = {'from': {}, 'to': {}},
48971 // determine base opacity and width
48972 if (tag === 'circle') {
48973 opacity = parseFloat(s.style('fill-opacity') || 0.5);
48974 width = parseFloat(s.style('r') || 15.5);
48976 opacity = parseFloat(s.style('stroke-opacity') || 0.7);
48977 width = parseFloat(s.style('stroke-width') || 10);
48980 // calculate from/to interpolation params..
48982 p.from.opacity = opacity * 0.6;
48983 p.to.opacity = opacity * 1.25;
48984 p.from.width = width * 0.9;
48985 p.to.width = width * (tag === 'circle' ? 1.5 : 1.25);
48991 function run(surface, fromTo) {
48992 var toFrom = (fromTo === 'from' ? 'to' : 'from'),
48993 currSelected = surface.selectAll(selector$$1),
48994 currClassed = surface.attr('class');
48996 if (done || currSelected.empty()) {
48997 selected.call(reset);
49001 if (!lodash.isEqual(currSelected.data(), selected.data()) || currClassed !== classed) {
49002 selected.call(reset);
49003 classed = currClassed;
49004 selected = currSelected.call(calcAnimationParams);
49009 .duration(duration)
49010 .call(setAnimationParams, fromTo)
49011 .on('end', function() {
49012 surface.call(run, toFrom);
49017 var breathe = function(surface) {
49019 timer$$1 = timer(function() {
49020 // wait for elements to actually become selected
49021 if (surface.selectAll(selector$$1).empty()) {
49025 surface.call(run, 'from');
49032 breathe.off = function() {
49044 function behaviorCopy(context) {
49045 var keybinding = d3keybinding('copy');
49048 function groupEntities(ids, graph) {
49049 var entities = ids.map(function (id) { return graph.entity(id); });
49050 return lodash.extend({relation: [], way: [], node: []},
49051 lodash.groupBy(entities, function(entity) { return entity.type; }));
49055 function getDescendants(id, graph, descendants) {
49056 var entity = graph.entity(id),
49059 descendants = descendants || {};
49061 if (entity.type === 'relation') {
49062 children = lodash.map(entity.members, 'id');
49063 } else if (entity.type === 'way') {
49064 children = entity.nodes;
49069 for (i = 0; i < children.length; i++) {
49070 if (!descendants[children[i]]) {
49071 descendants[children[i]] = true;
49072 descendants = getDescendants(children[i], graph, descendants);
49076 return descendants;
49080 function doCopy() {
49081 event.preventDefault();
49082 if (context.inIntro()) return;
49084 var graph = context.graph(),
49085 selected = groupEntities(context.selectedIDs(), graph),
49090 for (i = 0; i < selected.relation.length; i++) {
49091 entity = selected.relation[i];
49092 if (!skip[entity.id] && entity.isComplete(graph)) {
49093 canCopy.push(entity.id);
49094 skip = getDescendants(entity.id, graph, skip);
49097 for (i = 0; i < selected.way.length; i++) {
49098 entity = selected.way[i];
49099 if (!skip[entity.id]) {
49100 canCopy.push(entity.id);
49101 skip = getDescendants(entity.id, graph, skip);
49104 for (i = 0; i < selected.node.length; i++) {
49105 entity = selected.node[i];
49106 if (!skip[entity.id]) {
49107 canCopy.push(entity.id);
49111 context.copyIDs(canCopy);
49116 keybinding.on(uiCmd('⌘C'), doCopy);
49117 select(document).call(keybinding);
49122 copy.off = function() {
49123 select(document).call(keybinding.off);
49131 `behaviorDrag` is like `d3.behavior.drag`, with the following differences:
49133 * The `origin` function is expected to return an [x, y] tuple rather than an
49135 * The events are `start`, `move`, and `end`.
49136 (https://github.com/mbostock/d3/issues/563)
49137 * The `start` event is not dispatched until the first cursor movement occurs.
49138 (https://github.com/mbostock/d3/pull/368)
49139 * The `move` event has a `point` and `delta` [x, y] tuple properties rather
49140 than `x`, `y`, `dx`, and `dy` properties.
49141 * The `end` event is not dispatched if no movement occurs.
49142 * An `off` function is available that unbinds the drag's internal event handlers.
49143 * Delegation is supported via the `delegate` function.
49146 function behaviorDrag() {
49147 var event$$1 = dispatch('start', 'move', 'end'),
49151 event_, target, surface;
49154 function d3_eventCancel() {
49155 event.stopPropagation();
49156 event.preventDefault();
49159 function eventOf(thiz, argumentz) {
49160 return function(e1) {
49161 e1.target = drag$$1;
49162 customEvent(e1, event$$1.apply, event$$1, [e1.type, thiz, argumentz]);
49166 var d3_event_userSelectProperty = utilPrefixCSSProperty('UserSelect'),
49167 d3_event_userSelectSuppress = d3_event_userSelectProperty ?
49169 var selection$$1 = selection(),
49170 select$$1 = selection$$1.style(d3_event_userSelectProperty);
49171 selection$$1.style(d3_event_userSelectProperty, 'none');
49172 return function () {
49173 selection$$1.style(d3_event_userSelectProperty, select$$1);
49177 var w = select(window).on('selectstart.' + type, d3_eventCancel);
49178 return function () {
49179 w.on('selectstart.' + type, null);
49184 function mousedown() {
49186 event_ = eventOf(target, arguments);
49188 var eventTarget = event.target,
49189 touchId = event.touches ? event.changedTouches[0].identifier : null,
49193 selectEnable = d3_event_userSelectSuppress(touchId !== null ? 'drag-' + touchId : 'drag');
49195 var w = select(window)
49196 .on(touchId !== null ? 'touchmove.drag-' + touchId : 'mousemove.drag', dragmove)
49197 .on(touchId !== null ? 'touchend.drag-' + touchId : 'mouseup.drag', dragend, true);
49200 offset = origin.apply(target, arguments);
49201 offset = [offset[0] - origin_[0], offset[1] - origin_[1]];
49206 if (touchId === null) event.stopPropagation();
49209 var p = target.parentNode || surface;
49210 return touchId !== null ? touches(p).filter(function(p) {
49211 return p.identifier === touchId;
49216 function dragmove() {
49218 dx = p[0] - origin_[0],
49219 dy = p[1] - origin_[1];
49221 if (dx === 0 && dy === 0)
49236 point: [p[0] + offset[0], p[1] + offset[1]],
49242 function dragend() {
49249 if (event.target === eventTarget) w.on('click.drag', click, true);
49252 w.on(touchId !== null ? 'touchmove.drag-' + touchId : 'mousemove.drag', null)
49253 .on(touchId !== null ? 'touchend.drag-' + touchId : 'mouseup.drag', null);
49260 w.on('click.drag', null);
49265 function drag$$1(selection$$1) {
49266 var matchesSelector = utilPrefixDOMProperty('matchesSelector'),
49267 delegate = mousedown;
49270 delegate = function() {
49272 target = event.target;
49273 for (; target && target !== root; target = target.parentNode) {
49274 if (target[matchesSelector](selector$$1) &&
49275 (!filter || filter(target.__data__))) {
49276 return mousedown.call(target, target.__data__);
49282 selection$$1.on('mousedown.drag' + selector$$1, delegate)
49283 .on('touchstart.drag' + selector$$1, delegate);
49287 drag$$1.off = function(selection$$1) {
49288 selection$$1.on('mousedown.drag' + selector$$1, null)
49289 .on('touchstart.drag' + selector$$1, null);
49293 drag$$1.delegate = function(_) {
49294 if (!arguments.length) return selector$$1;
49300 drag$$1.filter = function(_) {
49301 if (!arguments.length) return origin;
49307 drag$$1.origin = function (_) {
49308 if (!arguments.length) return origin;
49314 drag$$1.cancel = function() {
49316 .on('mousemove.drag', null)
49317 .on('mouseup.drag', null);
49322 drag$$1.target = function() {
49323 if (!arguments.length) return target;
49324 target = arguments[0];
49325 event_ = eventOf(target, Array.prototype.slice.call(arguments, 1));
49330 drag$$1.surface = function() {
49331 if (!arguments.length) return surface;
49332 surface = arguments[0];
49337 return utilRebind(drag$$1, event$$1, 'on');
49340 function behaviorDrawWay(context, wayId, index, mode, baseGraph) {
49342 var way = context.entity(wayId),
49343 isArea = context.geometry(wayId) === 'area',
49345 annotation = t((way.isDegenerate() ?
49346 'operations.start.annotation.' :
49347 'operations.continue.annotation.') + context.geometry(wayId)),
49348 draw = behaviorDraw(context);
49350 var startIndex = typeof index === 'undefined' ? way.nodes.length - 1 : 0,
49351 start = osmNode({loc: context.graph().entity(way.nodes[startIndex]).loc}),
49352 end = osmNode({loc: context.map().mouseCoordinates()}),
49354 nodes: typeof index === 'undefined' ? [start.id, end.id] : [end.id, start.id],
49355 tags: lodash.clone(way.tags)
49358 var fn = context[way.isDegenerate() ? 'replace' : 'perform'];
49360 fn(actionAddEntity(end),
49361 actionAddVertex(wayId, end.id, index)
49364 fn(actionAddEntity(start),
49365 actionAddEntity(end),
49366 actionAddEntity(segment)
49371 function move(datum) {
49374 if (datum.type === 'node' && datum.id !== end.id) {
49377 } else if (datum.type === 'way' && datum.id !== segment.id) {
49378 var dims = context.map().dimensions(),
49379 mouse = context.mouse(),
49381 trySnap = mouse[0] > pad && mouse[0] < dims[0] - pad &&
49382 mouse[1] > pad && mouse[1] < dims[1] - pad;
49385 loc = geoChooseEdge(context.childNodes(datum), context.mouse(), context.projection).loc;
49390 loc = context.map().mouseCoordinates();
49393 context.replace(actionMoveNode(end.id, loc));
49397 function undone() {
49399 context.enter(modeBrowse$$1(context));
49403 function setActiveElements() {
49404 var active = isArea ? [wayId, end.id] : [segment.id, start.id, end.id];
49405 context.surface().selectAll(utilEntitySelector(active))
49406 .classed('active', true);
49410 var drawWay = function(surface) {
49411 draw.on('move', move)
49412 .on('click', drawWay.add)
49413 .on('clickWay', drawWay.addWay)
49414 .on('clickNode', drawWay.addNode)
49415 .on('undo', context.undo)
49416 .on('cancel', drawWay.cancel)
49417 .on('finish', drawWay.finish);
49420 .dblclickEnable(false)
49421 .on('drawn.draw', setActiveElements);
49423 setActiveElements();
49425 surface.call(draw);
49428 .on('undone.draw', undone);
49432 drawWay.off = function(surface) {
49437 .on('drawn.draw', null);
49439 surface.call(draw.off)
49440 .selectAll('.active')
49441 .classed('active', false);
49444 .on('undone.draw', null);
49448 function ReplaceTemporaryNode(newNode) {
49449 return function(graph) {
49452 .replace(way.addNode(newNode.id, index))
49457 .replace(graph.entity(wayId).addNode(newNode.id, index))
49466 // Accept the current position of the temporary node and continue drawing.
49467 drawWay.add = function(loc) {
49468 // prevent duplicate nodes
49469 var last = context.hasEntity(way.nodes[way.nodes.length - (isArea ? 2 : 1)]);
49470 if (last && last.loc[0] === loc[0] && last.loc[1] === loc[1]) return;
49472 var newNode = osmNode({loc: loc});
49475 actionAddEntity(newNode),
49476 ReplaceTemporaryNode(newNode),
49481 context.enter(mode);
49485 // Connect the way to an existing way.
49486 drawWay.addWay = function(loc, edge) {
49487 var previousEdge = startIndex ?
49488 [way.nodes[startIndex], way.nodes[startIndex - 1]] :
49489 [way.nodes[0], way.nodes[1]];
49491 // Avoid creating duplicate segments
49492 if (!isArea && geoEdgeEqual(edge, previousEdge))
49495 var newNode = osmNode({ loc: loc });
49498 actionAddMidpoint({ loc: loc, edge: edge}, newNode),
49499 ReplaceTemporaryNode(newNode),
49504 context.enter(mode);
49508 // Connect the way to an existing node and continue drawing.
49509 drawWay.addNode = function(node) {
49510 // Avoid creating duplicate segments
49511 if (way.areAdjacent(node.id, way.nodes[way.nodes.length - 1])) return;
49514 ReplaceTemporaryNode(node),
49519 context.enter(mode);
49523 // Finish the draw operation, removing the temporary node. If the way has enough
49524 // nodes to be valid, it's selected. Otherwise, return to browse mode.
49525 drawWay.finish = function() {
49529 window.setTimeout(function() {
49530 context.map().dblclickEnable(true);
49533 if (context.hasEntity(wayId)) {
49535 modeSelect(context, [wayId]).suppressMenu(true).newFeature(true)
49538 context.enter(modeBrowse$$1(context));
49543 // Cancel the draw operation and return to browse, deleting everything drawn.
49544 drawWay.cancel = function() {
49546 utilFunctor(baseGraph),
49547 t('operations.cancel_draw.annotation'));
49549 window.setTimeout(function() {
49550 context.map().dblclickEnable(true);
49554 context.enter(modeBrowse$$1(context));
49558 drawWay.tail = function(text) {
49567 function behaviorHash(context) {
49568 var s0 = null, // cached window.location.hash
49569 lat = 90 - 1e-8; // allowable latitude range
49572 var parser = function(map$$1, s) {
49573 var q = utilStringQs(s);
49574 var args = (q.map || '').split('/').map(Number);
49575 if (args.length < 3 || args.some(isNaN)) {
49576 return true; // replace bogus hash
49577 } else if (s !== formatter(map$$1).slice(1)) {
49578 map$$1.centerZoom([args[2],
49579 Math.min(lat, Math.max(-lat, args[1]))], args[0]);
49584 var formatter = function(map$$1) {
49585 var mode = context.mode(),
49586 center = map$$1.center(),
49587 zoom$$1 = map$$1.zoom(),
49588 precision = Math.max(0, Math.ceil(Math.log(zoom$$1) / Math.LN2)),
49589 q = lodash.omit(utilStringQs(window.location.hash.substring(1)), 'comment'),
49592 if (mode && mode.id === 'browse') {
49595 var selected = context.selectedIDs().filter(function(id) {
49596 return !context.entity(id).isNew();
49598 if (selected.length) {
49599 newParams.id = selected.join(',');
49603 newParams.map = zoom$$1.toFixed(2) +
49604 '/' + center[1].toFixed(precision) +
49605 '/' + center[0].toFixed(precision);
49607 return '#' + utilQsString(lodash.assign(q, newParams), true);
49611 function update() {
49612 if (context.inIntro()) return;
49613 var s1 = formatter(context.map());
49615 window.location.replace(s0 = s1); // don't recenter the map!
49620 var throttledUpdate = lodash.throttle(update, 500);
49623 function hashchange() {
49624 if (window.location.hash === s0) return; // ignore spurious hashchange events
49625 if (parser(context.map(), (s0 = window.location.hash).substring(1))) {
49626 update(); // replace bogus hash
49633 .on('move.hash', throttledUpdate);
49636 .on('enter.hash', throttledUpdate);
49639 .on('hashchange.hash', hashchange);
49641 if (window.location.hash) {
49642 var q = utilStringQs(window.location.hash.substring(1));
49643 if (q.id) context.zoomToEntity(q.id.split(',')[0], !q.map);
49644 if (q.comment) context.storage('comment', q.comment);
49646 if (q.map) hash.hadHash = true;
49651 hash.off = function() {
49652 throttledUpdate.cancel();
49655 .on('move.hash', null);
49658 .on('enter.hash', null);
49661 .on('hashchange.hash', null);
49663 window.location.hash = '';
49670 function behaviorLasso(context) {
49672 var behavior = function(selection$$1) {
49676 function mousedown() {
49677 var button = 0; // left
49678 if (event.button === button && event.shiftKey === true) {
49682 .on('mousemove.lasso', mousemove)
49683 .on('mouseup.lasso', mouseup);
49685 event.stopPropagation();
49690 function mousemove() {
49692 lasso = uiLasso(context);
49693 context.surface().call(lasso);
49696 lasso.p(context.mouse());
49700 function normalize(a, b) {
49702 [Math.min(a[0], b[0]), Math.min(a[1], b[1])],
49703 [Math.max(a[0], b[0]), Math.max(a[1], b[1])]];
49707 function lassoed() {
49708 if (!lasso) return [];
49710 var graph = context.graph(),
49711 bounds = lasso.extent().map(context.projection.invert),
49712 extent$$1 = geoExtent$$1(normalize(bounds[0], bounds[1]));
49714 return lodash.map(context.intersects(extent$$1).filter(function(entity) {
49715 return entity.type === 'node' &&
49716 geoPointInPolygon(context.projection(entity.loc), lasso.coordinates) &&
49717 !context.features().isHidden(entity, graph, entity.geometry(graph));
49722 function mouseup() {
49724 .on('mousemove.lasso', null)
49725 .on('mouseup.lasso', null);
49727 if (!lasso) return;
49729 var ids = lassoed();
49733 context.enter(modeSelect(context, ids));
49738 .on('mousedown.lasso', mousedown);
49742 behavior.off = function(selection$$1) {
49743 selection$$1.on('mousedown.lasso', null);
49750 function behaviorPaste(context) {
49751 var keybinding = d3keybinding('paste');
49753 function omitTag(v, k) {
49761 k === 'description' ||
49762 k.indexOf('name') !== -1 ||
49763 k.indexOf('wiki') === 0 ||
49764 k.indexOf('addr:') === 0 ||
49765 k.indexOf('contact:') === 0
49770 function doPaste() {
49771 event.preventDefault();
49772 if (context.inIntro()) return;
49774 var baseGraph = context.graph(),
49775 mouse$$1 = context.mouse(),
49776 projection = context.projection,
49777 viewport = geoExtent$$1(projection.clipExtent()).polygon();
49779 if (!geoPointInPolygon(mouse$$1, viewport)) return;
49781 var extent$$1 = geoExtent$$1(),
49782 oldIDs = context.copyIDs(),
49783 oldGraph = context.copyGraph(),
49786 if (!oldIDs.length) return;
49788 var action = actionCopyEntities(oldIDs, oldGraph);
49789 context.perform(action);
49791 var copies = action.copies();
49792 for (var id in copies) {
49793 var oldEntity = oldGraph.entity(id),
49794 newEntity = copies[id];
49796 extent$$1._extend(oldEntity.extent(oldGraph));
49797 newIDs.push(newEntity.id);
49799 actionChangeTags(newEntity.id, lodash.omit(newEntity.tags, omitTag))
49803 // Put pasted objects where mouse pointer is..
49804 var center = projection(extent$$1.center()),
49805 delta = [ mouse$$1[0] - center[0], mouse$$1[1] - center[1] ];
49807 context.perform(actionMove(newIDs, delta, projection));
49808 context.enter(modeMove$$1(context, newIDs, baseGraph));
49813 keybinding.on(uiCmd('⌘V'), doPaste);
49814 select(document).call(keybinding);
49819 paste.off = function() {
49820 select(document).call(keybinding.off);
49827 function behaviorSelect(context) {
49829 function keydown() {
49830 if (event && event.shiftKey) {
49832 .classed('behavior-multiselect', true);
49838 if (!event || !event.shiftKey) {
49840 .classed('behavior-multiselect', false);
49846 var datum = event.target.__data__,
49847 lasso = select('#surface .lasso').node(),
49848 mode = context.mode();
49850 if (!(datum instanceof osmEntity$$1)) {
49851 if (!event.shiftKey && !lasso && mode.id !== 'browse')
49852 context.enter(modeBrowse$$1(context));
49854 } else if (!event.shiftKey && !lasso) {
49855 // Avoid re-entering Select mode with same entity.
49856 if (context.selectedIDs().length !== 1 || context.selectedIDs()[0] !== datum.id) {
49857 context.enter(modeSelect(context, [datum.id]));
49859 mode.suppressMenu(false).reselect();
49861 } else if (context.selectedIDs().indexOf(datum.id) >= 0) {
49862 var selectedIDs = lodash.without(context.selectedIDs(), datum.id);
49863 context.enter(selectedIDs.length ? modeSelect(context, selectedIDs) : modeBrowse$$1(context));
49866 context.enter(modeSelect(context, context.selectedIDs().concat([datum.id])));
49871 var behavior = function(selection$$1) {
49873 .on('keydown.select', keydown)
49874 .on('keyup.select', keyup);
49876 selection$$1.on('click.select', click);
49882 behavior.off = function(selection$$1) {
49884 .on('keydown.select', null)
49885 .on('keyup.select', null);
49887 selection$$1.on('click.select', null);
49896 function modeAddArea$$1(context) {
49900 title: t('modes.add_area.title'),
49901 description: t('modes.add_area.description'),
49905 var behavior = behaviorAddWay(context)
49906 .tail(t('modes.add_area.tail'))
49907 .on('start', start)
49908 .on('startFromWay', startFromWay)
49909 .on('startFromNode', startFromNode),
49910 defaultTags = { area: 'yes' };
49913 function start(loc) {
49914 var graph = context.graph(),
49915 node = osmNode({ loc: loc }),
49916 way = osmWay({ tags: defaultTags });
49919 actionAddEntity(node),
49920 actionAddEntity(way),
49921 actionAddVertex(way.id, node.id),
49922 actionAddVertex(way.id, node.id)
49925 context.enter(modeDrawArea(context, way.id, graph));
49929 function startFromWay(loc, edge) {
49930 var graph = context.graph(),
49931 node = osmNode({ loc: loc }),
49932 way = osmWay({ tags: defaultTags });
49935 actionAddEntity(node),
49936 actionAddEntity(way),
49937 actionAddVertex(way.id, node.id),
49938 actionAddVertex(way.id, node.id),
49939 actionAddMidpoint({ loc: loc, edge: edge }, node)
49942 context.enter(modeDrawArea(context, way.id, graph));
49946 function startFromNode(node) {
49947 var graph = context.graph(),
49948 way = osmWay({ tags: defaultTags });
49951 actionAddEntity(way),
49952 actionAddVertex(way.id, node.id),
49953 actionAddVertex(way.id, node.id)
49956 context.enter(modeDrawArea(context, way.id, graph));
49960 mode.enter = function() {
49961 context.install(behavior);
49965 mode.exit = function() {
49966 context.uninstall(behavior);
49973 function modeAddLine$$1(context) {
49977 title: t('modes.add_line.title'),
49978 description: t('modes.add_line.description'),
49982 var behavior = behaviorAddWay(context)
49983 .tail(t('modes.add_line.tail'))
49984 .on('start', start)
49985 .on('startFromWay', startFromWay)
49986 .on('startFromNode', startFromNode);
49989 function start(loc) {
49990 var baseGraph = context.graph(),
49991 node = osmNode({ loc: loc }),
49995 actionAddEntity(node),
49996 actionAddEntity(way),
49997 actionAddVertex(way.id, node.id)
50000 context.enter(modeDrawLine(context, way.id, baseGraph));
50004 function startFromWay(loc, edge) {
50005 var baseGraph = context.graph(),
50006 node = osmNode({ loc: loc }),
50010 actionAddEntity(node),
50011 actionAddEntity(way),
50012 actionAddVertex(way.id, node.id),
50013 actionAddMidpoint({ loc: loc, edge: edge }, node)
50016 context.enter(modeDrawLine(context, way.id, baseGraph));
50020 function startFromNode(node) {
50021 var baseGraph = context.graph(),
50025 actionAddEntity(way),
50026 actionAddVertex(way.id, node.id)
50029 context.enter(modeDrawLine(context, way.id, baseGraph));
50033 mode.enter = function() {
50034 context.install(behavior);
50038 mode.exit = function() {
50039 context.uninstall(behavior);
50045 function modeAddPoint$$1(context) {
50049 title: t('modes.add_point.title'),
50050 description: t('modes.add_point.description'),
50054 var behavior = behaviorDraw(context)
50055 .tail(t('modes.add_point.tail'))
50057 .on('clickWay', addWay)
50058 .on('clickNode', addNode)
50059 .on('cancel', cancel)
50060 .on('finish', cancel);
50063 function add(loc) {
50064 var node = osmNode({ loc: loc });
50067 actionAddEntity(node),
50068 t('operations.add.annotation.point')
50072 modeSelect(context, [node.id]).suppressMenu(true).newFeature(true)
50077 function addWay(loc) {
50082 function addNode(node) {
50087 function cancel() {
50088 context.enter(modeBrowse$$1(context));
50092 mode.enter = function() {
50093 context.install(behavior);
50097 mode.exit = function() {
50098 context.uninstall(behavior);
50105 function modeBrowse$$1(context) {
50109 title: t('modes.browse.title'),
50110 description: t('modes.browse.description')
50114 behaviorPaste(context),
50115 behaviorHover(context).on('hover', context.ui().sidebar.hover),
50116 behaviorSelect(context),
50117 behaviorLasso(context),
50118 modeDragNode$$1(context).behavior
50122 mode.enter = function() {
50123 behaviors.forEach(function(behavior) {
50124 context.install(behavior);
50127 // Get focus on the body.
50128 if (document.activeElement && document.activeElement.blur) {
50129 document.activeElement.blur();
50133 context.ui().sidebar.show(sidebar);
50135 context.ui().sidebar.select(null);
50140 mode.exit = function() {
50141 context.ui().sidebar.hover.cancel();
50142 behaviors.forEach(function(behavior) {
50143 context.uninstall(behavior);
50147 context.ui().sidebar.hide();
50152 mode.sidebar = function(_) {
50153 if (!arguments.length) return sidebar;
50162 function modeDragNode$$1(context) {
50173 hover = behaviorHover(context).altDisables(true).on('hover', context.ui().sidebar.hover),
50174 edit = behaviorEdit(context);
50177 function edge(point, size) {
50178 var pad = [30, 100, 30, 100];
50179 if (point[0] > size[0] - pad[0]) return [-10, 0];
50180 else if (point[0] < pad[2]) return [10, 0];
50181 else if (point[1] > size[1] - pad[1]) return [0, -10];
50182 else if (point[1] < pad[3]) return [0, 10];
50187 function startNudge(nudge) {
50188 if (nudgeInterval) window.clearInterval(nudgeInterval);
50189 nudgeInterval = window.setInterval(function() {
50190 context.pan(nudge);
50195 function stopNudge() {
50196 if (nudgeInterval) window.clearInterval(nudgeInterval);
50197 nudgeInterval = null;
50201 function moveAnnotation(entity) {
50202 return t('operations.move.annotation.' + entity.geometry(context.graph()));
50206 function connectAnnotation(entity) {
50207 return t('operations.connect.annotation.' + entity.geometry(context.graph()));
50211 function origin(entity) {
50212 return context.projection(entity.loc);
50216 function start(entity) {
50217 isCancelled = event.sourceEvent.shiftKey ||
50218 context.features().hasHiddenConnections(entity, context.graph());
50220 if (isCancelled) return behavior.cancel();
50222 wasMidpoint = entity.type === 'midpoint';
50224 var midpoint = entity;
50225 entity = osmNode();
50226 context.perform(actionAddMidpoint(midpoint, entity));
50228 var vertex = context.surface().selectAll('.' + entity.id);
50229 behavior.target(vertex.node(), entity);
50232 context.perform(actionNoop());
50235 activeIDs = lodash.map(context.graph().parentWays(entity), 'id');
50236 activeIDs.push(entity.id);
50237 context.enter(mode);
50242 if (event.sourceEvent.altKey) {
50246 return event.sourceEvent.target.__data__ || {};
50250 // via https://gist.github.com/shawnbot/4166283
50251 function childOf(p, c) {
50252 if (p === c) return false;
50253 while (c && c !== p) c = c.parentNode;
50258 function move(entity) {
50259 if (isCancelled) return;
50260 event.sourceEvent.stopPropagation();
50262 var nudge = childOf(context.container().node(),
50263 event.sourceEvent.toElement) &&
50264 edge(event.point, context.map().dimensions());
50266 if (nudge) startNudge(nudge);
50269 var loc = context.projection.invert(event.point);
50272 if (d.type === 'node' && d.id !== entity.id) {
50274 } else if (d.type === 'way' && !select(event.sourceEvent.target).classed('fill')) {
50275 loc = geoChooseEdge(context.childNodes(d), context.mouse(), context.projection).loc;
50279 actionMoveNode(entity.id, loc),
50280 moveAnnotation(entity)
50285 function end(entity) {
50286 if (isCancelled) return;
50290 if (d.type === 'way') {
50291 var choice = geoChooseEdge(context.childNodes(d), context.mouse(), context.projection);
50293 actionAddMidpoint({ loc: choice.loc, edge: [d.nodes[choice.index - 1], d.nodes[choice.index]] }, entity),
50294 connectAnnotation(d)
50297 } else if (d.type === 'node' && d.id !== entity.id) {
50299 actionConnect([d.id, entity.id]),
50300 connectAnnotation(d)
50303 } else if (wasMidpoint) {
50306 t('operations.add.annotation.vertex')
50312 moveAnnotation(entity)
50316 var reselection = selectedIDs.filter(function(id) {
50317 return context.graph().hasEntity(id);
50320 if (reselection.length) {
50321 context.enter(modeSelect(context, reselection).suppressMenu(true));
50323 context.enter(modeBrowse$$1(context));
50328 function cancel() {
50330 context.enter(modeBrowse$$1(context));
50334 function setActiveElements() {
50335 context.surface().selectAll(utilEntitySelector(activeIDs))
50336 .classed('active', true);
50340 var behavior = behaviorDrag()
50341 .delegate('g.node, g.point, g.midpoint')
50342 .surface(context.surface().node())
50344 .on('start', start)
50349 mode.enter = function() {
50350 context.install(hover);
50351 context.install(edit);
50354 .on('undone.drag-node', cancel);
50357 .on('drawn.drag-node', setActiveElements);
50359 setActiveElements();
50363 mode.exit = function() {
50364 context.ui().sidebar.hover.cancel();
50365 context.uninstall(hover);
50366 context.uninstall(edit);
50369 .on('undone.drag-node', null);
50372 .on('drawn.drag-node', null);
50375 .selectAll('.active')
50376 .classed('active', false);
50382 mode.selectedIDs = function(_) {
50383 if (!arguments.length) return selectedIDs;
50389 mode.behavior = behavior;
50395 function modeDrawArea(context, wayId, baseGraph) {
50404 mode.enter = function() {
50405 var way = context.entity(wayId),
50406 headId = way.nodes[way.nodes.length - 2],
50407 tailId = way.first();
50409 behavior = behaviorDrawWay(context, wayId, -1, mode, baseGraph)
50410 .tail(t('modes.draw_area.tail'));
50412 var addNode = behavior.addNode;
50414 behavior.addNode = function(node) {
50415 if (node.id === headId || node.id === tailId) {
50422 context.install(behavior);
50426 mode.exit = function() {
50427 context.uninstall(behavior);
50431 mode.selectedIDs = function() {
50439 function modeDrawLine(context, wayId, baseGraph, affix) {
50448 mode.enter = function() {
50449 var way = context.entity(wayId),
50450 index = (affix === 'prefix') ? 0 : undefined,
50451 headId = (affix === 'prefix') ? way.first() : way.last();
50453 behavior = behaviorDrawWay(context, wayId, index, mode, baseGraph)
50454 .tail(t('modes.draw_line.tail'));
50456 var addNode = behavior.addNode;
50458 behavior.addNode = function(node) {
50459 if (node.id === headId) {
50466 context.install(behavior);
50470 mode.exit = function() {
50471 context.uninstall(behavior);
50475 mode.selectedIDs = function() {
50483 function modeMove$$1(context, entityIDs, baseGraph) {
50489 var keybinding = d3keybinding('move'),
50490 edit = behaviorEdit(context),
50491 annotation = entityIDs.length === 1 ?
50492 t('operations.move.annotation.' + context.geometry(entityIDs[0])) :
50493 t('operations.move.annotation.multiple'),
50499 function vecSub(a, b) { return [a[0] - b[0], a[1] - b[1]]; }
50502 function edge(point, size) {
50503 var pad = [30, 100, 30, 100];
50504 if (point[0] > size[0] - pad[0]) return [-10, 0];
50505 else if (point[0] < pad[2]) return [10, 0];
50506 else if (point[1] > size[1] - pad[1]) return [0, -10];
50507 else if (point[1] < pad[3]) return [0, 10];
50512 function startNudge(nudge) {
50513 if (nudgeInterval) window.clearInterval(nudgeInterval);
50514 nudgeInterval = window.setInterval(function() {
50515 context.pan(nudge);
50517 var currMouse = context.mouse(),
50518 origMouse = context.projection(origin),
50519 delta = vecSub(vecSub(currMouse, origMouse), nudge),
50520 action = actionMove(entityIDs, delta, context.projection, cache);
50522 context.overwrite(action, annotation);
50528 function stopNudge() {
50529 if (nudgeInterval) window.clearInterval(nudgeInterval);
50530 nudgeInterval = null;
50535 var currMouse = context.mouse(),
50536 origMouse = context.projection(origin),
50537 delta = vecSub(currMouse, origMouse),
50538 action = actionMove(entityIDs, delta, context.projection, cache);
50540 context.overwrite(action, annotation);
50542 var nudge = edge(currMouse, context.map().dimensions());
50543 if (nudge) startNudge(nudge);
50548 function finish() {
50549 event.stopPropagation();
50550 context.enter(modeSelect(context, entityIDs).suppressMenu(true));
50555 function cancel() {
50557 while (context.graph() !== baseGraph) context.pop();
50558 context.enter(modeBrowse$$1(context));
50561 context.enter(modeSelect(context, entityIDs).suppressMenu(true));
50567 function undone() {
50568 context.enter(modeBrowse$$1(context));
50572 mode.enter = function() {
50573 origin = context.map().mouseCoordinates();
50576 context.install(edit);
50584 .on('mousemove.move', move)
50585 .on('click.move', finish);
50588 .on('undone.move', undone);
50599 mode.exit = function() {
50602 context.uninstall(edit);
50605 .on('mousemove.move', null)
50606 .on('click.move', null);
50609 .on('undone.move', null);
50618 function modeRotateWay$$1(context, wayId) {
50624 var keybinding = d3keybinding('rotate-way'),
50625 edit = behaviorEdit(context);
50628 mode.enter = function() {
50629 context.install(edit);
50631 var annotation = t('operations.rotate.annotation.' + context.geometry(wayId)),
50632 way = context.graph().entity(wayId),
50633 nodes = lodash.uniq(context.graph().childNodes(way)),
50634 points = nodes.map(function(n) { return context.projection(n.loc); }),
50635 pivot = d3polygonCentroid(points),
50644 .on('mousemove.rotate-way', rotate)
50645 .on('click.rotate-way', finish);
50648 .on('undone.rotate-way', undone);
50658 function rotate() {
50659 var mousePoint = context.mouse(),
50660 newAngle = Math.atan2(mousePoint[1] - pivot[1], mousePoint[0] - pivot[0]);
50662 if (typeof angle === 'undefined') angle = newAngle;
50665 actionRotateWay(wayId, pivot, newAngle - angle, context.projection),
50673 function finish() {
50674 event.stopPropagation();
50675 context.enter(modeSelect(context, [wayId]).suppressMenu(true));
50679 function cancel() {
50681 context.enter(modeSelect(context, [wayId]).suppressMenu(true));
50685 function undone() {
50686 context.enter(modeBrowse$$1(context));
50691 mode.exit = function() {
50692 context.uninstall(edit);
50695 .on('mousemove.rotate-way', null)
50696 .on('click.rotate-way', null);
50699 .on('undone.rotate-way', null);
50708 function modeSave$$1(context) {
50713 var ui = uiCommit(context)
50714 .on('cancel', cancel)
50718 function cancel() {
50719 context.enter(modeBrowse$$1(context));
50723 function save(e, tryAgain) {
50724 function withChildNodes(ids, graph) {
50725 return lodash.uniq(lodash.reduce(ids, function(result, id) {
50726 var e = graph.entity(id);
50727 if (e.type === 'way') {
50729 var cn = graph.childNodes(e);
50730 result.push.apply(result, lodash.map(lodash.filter(cn, 'version'), 'id'));
50732 /* eslint-disable no-console */
50733 if (typeof console !== 'undefined') console.error(err);
50734 /* eslint-enable no-console */
50738 }, lodash.clone(ids)));
50741 var loading = uiLoading(context).message(t('save.uploading')).blocking(true),
50742 history = context.history(),
50743 origChanges = history.changes(actionDiscardTags(history.difference())),
50744 localGraph = context.graph(),
50745 remoteGraph = coreGraph$$1(history.base(), true),
50746 modified = lodash.filter(history.difference().summary(), {changeType: 'modified'}),
50747 toCheck = lodash.map(lodash.map(modified, 'entity'), 'id'),
50748 toLoad = withChildNodes(toCheck, localGraph),
50752 if (!tryAgain) history.perform(actionNoop()); // checkpoint
50753 context.container().call(loading);
50755 if (toCheck.length) {
50756 context.connection().loadMultiple(toLoad, loaded);
50762 // Reload modified entities into an alternate graph and check for conflicts..
50763 function loaded(err, result) {
50764 if (errors.length) return;
50768 msg: err.responseText,
50769 details: [ t('save.status_code', { code: err.status }) ]
50775 lodash.each(result.data, function(entity) {
50776 remoteGraph.replace(entity);
50777 toLoad = lodash.without(toLoad, entity.id);
50779 // Because loadMultiple doesn't download /full like loadEntity,
50780 // need to also load children that aren't already being checked..
50781 if (!entity.visible) return;
50782 if (entity.type === 'way') {
50783 loadMore.push.apply(loadMore,
50784 lodash.difference(entity.nodes, toCheck, toLoad, loadMore));
50785 } else if (entity.type === 'relation' && entity.isMultipolygon()) {
50786 loadMore.push.apply(loadMore,
50787 lodash.difference(lodash.map(entity.members, 'id'), toCheck, toLoad, loadMore));
50791 if (loadMore.length) {
50792 toLoad.push.apply(toLoad, loadMore);
50793 context.connection().loadMultiple(loadMore, loaded);
50796 if (!toLoad.length) {
50803 function checkConflicts() {
50804 function choice(id, text$$1, action) {
50805 return { id: id, text: text$$1, action: function() { history.replace(action); } };
50807 function formatUser(d) {
50808 return '<a href="' + context.connection().userURL(d) + '" target="_blank">' + d + '</a>';
50810 function entityName(entity) {
50811 return utilDisplayName(entity) || (utilDisplayType(entity.id) + ' ' + entity.id);
50814 function compareVersions(local$$1, remote) {
50815 if (local$$1.version !== remote.version) return false;
50817 if (local$$1.type === 'way') {
50818 var children = lodash.union(local$$1.nodes, remote.nodes);
50820 for (var i = 0; i < children.length; i++) {
50821 var a = localGraph.hasEntity(children[i]),
50822 b = remoteGraph.hasEntity(children[i]);
50824 if (a && b && a.version !== b.version) return false;
50831 lodash.each(toCheck, function(id) {
50832 var local$$1 = localGraph.entity(id),
50833 remote = remoteGraph.entity(id);
50835 if (compareVersions(local$$1, remote)) return;
50837 var action = actionMergeRemoteChanges,
50838 merge$$1 = action(id, localGraph, remoteGraph, formatUser);
50840 history.replace(merge$$1);
50842 var mergeConflicts = merge$$1.conflicts();
50843 if (!mergeConflicts.length) return; // merged safely
50845 var forceLocal = action(id, localGraph, remoteGraph).withOption('force_local'),
50846 forceRemote = action(id, localGraph, remoteGraph).withOption('force_remote'),
50847 keepMine = t('save.conflict.' + (remote.visible ? 'keep_local' : 'restore')),
50848 keepTheirs = t('save.conflict.' + (remote.visible ? 'keep_remote' : 'delete'));
50852 name: entityName(local$$1),
50853 details: mergeConflicts,
50856 choice(id, keepMine, forceLocal),
50857 choice(id, keepTheirs, forceRemote)
50866 function finalize() {
50867 if (conflicts.length) {
50868 conflicts.sort(function(a,b) { return b.id.localeCompare(a.id); });
50870 } else if (errors.length) {
50873 var changes = history.changes(actionDiscardTags(history.difference()));
50874 if (changes.modified.length || changes.created.length || changes.deleted.length) {
50875 context.connection().putChangeset(
50879 history.imageryUsed(),
50880 function(err, changeset_id) {
50883 msg: err.responseText,
50884 details: [ t('save.status_code', { code: err.status }) ]
50888 history.clearSaved();
50889 success(e, changeset_id);
50890 // Add delay to allow for postgres replication #1646 #2678
50891 window.setTimeout(function() {
50897 } else { // changes were insignificant or reverted by user
50906 function showConflicts() {
50907 var selection$$1 = context.container()
50908 .select('#sidebar')
50910 .attr('class','sidebar-component');
50914 selection$$1.call(uiConflicts(context)
50916 .on('download', function() {
50917 var data = JXON.stringify(context.connection().osmChangeJXON('CHANGEME', origChanges)),
50918 win = window.open('data:text/xml,' + encodeURIComponent(data), '_blank');
50921 .on('cancel', function() {
50923 selection$$1.remove();
50925 .on('save', function() {
50926 for (var i = 0; i < conflicts.length; i++) {
50927 if (conflicts[i].chosen === 1) { // user chose "keep theirs"
50928 var entity = context.hasEntity(conflicts[i].id);
50929 if (entity && entity.type === 'way') {
50930 var children = lodash.uniq(entity.nodes);
50931 for (var j = 0; j < children.length; j++) {
50932 history.replace(actionRevert(children[j]));
50935 history.replace(actionRevert(conflicts[i].id));
50939 selection$$1.remove();
50946 function showErrors() {
50947 var selection$$1 = uiConfirm(context.container());
50953 .select('.modal-section.header')
50955 .text(t('save.error'));
50957 addErrors(selection$$1, errors);
50958 selection$$1.okButton();
50962 function addErrors(selection$$1, data) {
50963 var message = selection$$1
50964 .select('.modal-section.message-text');
50966 var items = message
50967 .selectAll('.error-container')
50970 var enter = items.enter()
50972 .attr('class', 'error-container');
50976 .attr('class', 'error-description')
50978 .classed('hide-toggle', true)
50979 .text(function(d) { return d.msg || t('save.unknown_error_details'); })
50980 .on('click', function() {
50981 var error = select(this),
50982 detail = select(this.nextElementSibling),
50983 exp = error.classed('expanded');
50985 detail.style('display', exp ? 'none' : 'block');
50986 error.classed('expanded', !exp);
50988 event.preventDefault();
50991 var details = enter
50993 .attr('class', 'error-detail-container')
50994 .style('display', 'none');
50998 .attr('class', 'error-detail-list')
51000 .data(function(d) { return d.details || []; })
51003 .attr('class', 'error-detail-item')
51004 .text(function(d) { return d; });
51013 function success(e, changeset_id) {
51014 context.enter(modeBrowse$$1(context)
51015 .sidebar(uiSuccess(context)
51020 .on('cancel', function() {
51021 context.ui().sidebar.hide();
51028 mode.enter = function() {
51029 context.connection().authenticate(function(err) {
51033 context.ui().sidebar.show(ui);
51039 mode.exit = function() {
51040 context.ui().sidebar.hide();
51046 function operationCircularize(selectedIDs, context) {
51047 var entityId = selectedIDs[0],
51048 entity = context.entity(entityId),
51049 extent = entity.extent(context.graph()),
51050 geometry = context.geometry(entityId),
51051 action = actionCircularize(entityId, context.projection);
51053 var operation = function() {
51054 var annotation = t('operations.circularize.annotation.' + geometry);
51055 context.perform(action, annotation);
51059 operation.available = function() {
51060 return selectedIDs.length === 1 &&
51061 entity.type === 'way' &&
51062 lodash.uniq(entity.nodes).length > 1;
51066 operation.disabled = function() {
51068 if (extent.percentContainedIn(context.extent()) < 0.8) {
51069 reason = 'too_large';
51070 } else if (context.hasHiddenConnections(entityId)) {
51071 reason = 'connected_to_hidden';
51073 return action.disabled(context.graph()) || reason;
51077 operation.tooltip = function() {
51078 var disable = operation.disabled();
51080 t('operations.circularize.' + disable) :
51081 t('operations.circularize.description.' + geometry);
51085 operation.id = 'circularize';
51086 operation.keys = [t('operations.circularize.key')];
51087 operation.title = t('operations.circularize.title');
51093 function operationContinue(selectedIDs, context) {
51094 var graph = context.graph(),
51095 entities = selectedIDs.map(function(id) { return graph.entity(id); }),
51096 geometries = lodash.extend({ line: [], vertex: [] },
51097 lodash.groupBy(entities, function(entity) { return entity.geometry(graph); })),
51098 vertex = geometries.vertex[0];
51101 function candidateWays() {
51102 return graph.parentWays(vertex).filter(function(parent) {
51103 return parent.geometry(graph) === 'line' &&
51104 parent.affix(vertex.id) &&
51105 (geometries.line.length === 0 || geometries.line[0] === parent);
51110 var operation = function() {
51111 var candidate = candidateWays()[0];
51113 modeDrawLine(context, candidate.id, context.graph(), candidate.affix(vertex.id))
51118 operation.available = function() {
51119 return geometries.vertex.length === 1 && geometries.line.length <= 1 &&
51120 !context.features().hasHiddenConnections(vertex, context.graph());
51124 operation.disabled = function() {
51125 var candidates = candidateWays();
51126 if (candidates.length === 0)
51127 return 'not_eligible';
51128 if (candidates.length > 1)
51133 operation.tooltip = function() {
51134 var disable = operation.disabled();
51136 t('operations.continue.' + disable) :
51137 t('operations.continue.description');
51141 operation.id = 'continue';
51142 operation.keys = [t('operations.continue.key')];
51143 operation.title = t('operations.continue.title');
51149 function operationDelete(selectedIDs, context) {
51150 var action = actionDeleteMultiple(selectedIDs);
51152 var operation = function() {
51156 if (selectedIDs.length > 1) {
51157 annotation = t('operations.delete.annotation.multiple', { n: selectedIDs.length });
51160 var id = selectedIDs[0],
51161 entity = context.entity(id),
51162 geometry = context.geometry(id),
51163 parents = context.graph().parentWays(entity),
51164 parent = parents[0];
51166 annotation = t('operations.delete.annotation.' + geometry);
51168 // Select the next closest node in the way.
51169 if (geometry === 'vertex' && parents.length === 1 && parent.nodes.length > 2) {
51170 var nodes = parent.nodes,
51171 i = nodes.indexOf(id);
51175 } else if (i === nodes.length - 1) {
51178 var a = geoSphericalDistance(entity.loc, context.entity(nodes[i - 1]).loc),
51179 b = geoSphericalDistance(entity.loc, context.entity(nodes[i + 1]).loc);
51180 i = a < b ? i - 1 : i + 1;
51183 nextSelectedID = nodes[i];
51187 if (nextSelectedID && context.hasEntity(nextSelectedID)) {
51188 context.enter(modeSelect(context, [nextSelectedID]));
51190 context.enter(modeBrowse$$1(context));
51193 context.perform(action, annotation);
51197 operation.available = function() {
51202 operation.disabled = function() {
51204 if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
51205 reason = 'connected_to_hidden';
51207 return action.disabled(context.graph()) || reason;
51211 operation.tooltip = function() {
51212 var disable = operation.disabled();
51214 t('operations.delete.' + disable) :
51215 t('operations.delete.description');
51219 operation.id = 'delete';
51220 operation.keys = [uiCmd('⌘⌫'), uiCmd('⌘⌦'), uiCmd('⌦')];
51221 operation.title = t('operations.delete.title');
51227 function operationDisconnect(selectedIDs, context) {
51228 var vertices = lodash.filter(selectedIDs, function(entityId) {
51229 return context.geometry(entityId) === 'vertex';
51232 var entityId = vertices[0],
51233 action = actionDisconnect(entityId);
51235 if (selectedIDs.length > 1) {
51236 action.limitWays(lodash.without(selectedIDs, entityId));
51239 var operation = function() {
51240 context.perform(action, t('operations.disconnect.annotation'));
51244 operation.available = function() {
51245 return vertices.length === 1;
51249 operation.disabled = function() {
51251 if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
51252 reason = 'connected_to_hidden';
51254 return action.disabled(context.graph()) || reason;
51258 operation.tooltip = function() {
51259 var disable = operation.disabled();
51261 t('operations.disconnect.' + disable) :
51262 t('operations.disconnect.description');
51266 operation.id = 'disconnect';
51267 operation.keys = [t('operations.disconnect.key')];
51268 operation.title = t('operations.disconnect.title');
51274 function operationMerge(selectedIDs, context) {
51275 var join = actionJoin(selectedIDs),
51276 merge = actionMerge(selectedIDs),
51277 mergePolygon = actionMergePolygon(selectedIDs);
51279 var operation = function() {
51280 var annotation = t('operations.merge.annotation', {n: selectedIDs.length}),
51283 if (!join.disabled(context.graph())) {
51285 } else if (!merge.disabled(context.graph())) {
51288 action = mergePolygon;
51291 context.perform(action, annotation);
51292 var ids = selectedIDs.filter(function(id) { return context.hasEntity(id); });
51293 context.enter(modeSelect(context, ids).suppressMenu(true));
51297 operation.available = function() {
51298 return selectedIDs.length >= 2;
51302 operation.disabled = function() {
51303 return join.disabled(context.graph()) &&
51304 merge.disabled(context.graph()) &&
51305 mergePolygon.disabled(context.graph());
51309 operation.tooltip = function() {
51310 var j = join.disabled(context.graph()),
51311 m = merge.disabled(context.graph()),
51312 p = mergePolygon.disabled(context.graph());
51314 if (j === 'restriction' && m && p) {
51315 return t('operations.merge.restriction',
51316 { relation: context.presets().item('type/restriction').name() });
51319 if (p === 'incomplete_relation' && j && m) {
51320 return t('operations.merge.incomplete_relation');
51324 return t('operations.merge.' + j);
51327 return t('operations.merge.description');
51331 operation.id = 'merge';
51332 operation.keys = [t('operations.merge.key')];
51333 operation.title = t('operations.merge.title');
51339 function operationMove(selectedIDs, context) {
51340 var extent = selectedIDs.reduce(function(extent, id) {
51341 return extent.extend(context.entity(id).extent(context.graph()));
51342 }, geoExtent$$1());
51344 var operation = function() {
51345 context.enter(modeMove$$1(context, selectedIDs));
51349 operation.available = function() {
51350 return selectedIDs.length > 1 ||
51351 context.entity(selectedIDs[0]).type !== 'node';
51355 operation.disabled = function() {
51357 if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
51358 reason = 'too_large';
51359 } else if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
51360 reason = 'connected_to_hidden';
51363 return actionMove(selectedIDs).disabled(context.graph()) || reason;
51367 operation.tooltip = function() {
51368 var disable = operation.disabled();
51370 t('operations.move.' + disable) :
51371 t('operations.move.description');
51375 operation.id = 'move';
51376 operation.keys = [t('operations.move.key')];
51377 operation.title = t('operations.move.title');
51383 function operationOrthogonalize(selectedIDs, context) {
51384 var entityId = selectedIDs[0],
51385 entity = context.entity(entityId),
51386 extent = entity.extent(context.graph()),
51387 geometry = context.geometry(entityId),
51388 action = actionOrthogonalize(entityId, context.projection);
51390 var operation = function() {
51391 var annotation = t('operations.orthogonalize.annotation.' + geometry);
51392 context.perform(action, annotation);
51396 operation.available = function() {
51397 return selectedIDs.length === 1 &&
51398 entity.type === 'way' &&
51399 entity.isClosed() &&
51400 lodash.uniq(entity.nodes).length > 2;
51404 operation.disabled = function() {
51406 if (extent.percentContainedIn(context.extent()) < 0.8) {
51407 reason = 'too_large';
51408 } else if (context.hasHiddenConnections(entityId)) {
51409 reason = 'connected_to_hidden';
51411 return action.disabled(context.graph()) || reason;
51415 operation.tooltip = function() {
51416 var disable = operation.disabled();
51418 t('operations.orthogonalize.' + disable) :
51419 t('operations.orthogonalize.description.' + geometry);
51423 operation.id = 'orthogonalize';
51424 operation.keys = [t('operations.orthogonalize.key')];
51425 operation.title = t('operations.orthogonalize.title');
51431 function operationReverse(selectedIDs, context) {
51432 var entityId = selectedIDs[0];
51434 var operation = function() {
51436 actionReverse(entityId),
51437 t('operations.reverse.annotation')
51442 operation.available = function() {
51443 return selectedIDs.length === 1 &&
51444 context.geometry(entityId) === 'line';
51448 operation.disabled = function() {
51453 operation.tooltip = function() {
51454 return t('operations.reverse.description');
51458 operation.id = 'reverse';
51459 operation.keys = [t('operations.reverse.key')];
51460 operation.title = t('operations.reverse.title');
51466 function operationRotate(selectedIDs, context) {
51467 var entityId = selectedIDs[0],
51468 entity = context.entity(entityId),
51469 extent = entity.extent(context.graph()),
51470 geometry = context.geometry(entityId);
51472 var operation = function() {
51473 context.enter(modeRotateWay$$1(context, entityId));
51477 operation.available = function() {
51478 if (selectedIDs.length !== 1 || entity.type !== 'way')
51480 if (geometry === 'area')
51482 if (entity.isClosed() &&
51483 context.graph().parentRelations(entity).some(function(r) { return r.isMultipolygon(); }))
51489 operation.disabled = function() {
51490 if (extent.percentContainedIn(context.extent()) < 0.8) {
51491 return 'too_large';
51492 } else if (context.hasHiddenConnections(entityId)) {
51493 return 'connected_to_hidden';
51500 operation.tooltip = function() {
51501 var disable = operation.disabled();
51503 t('operations.rotate.' + disable) :
51504 t('operations.rotate.description');
51508 operation.id = 'rotate';
51509 operation.keys = [t('operations.rotate.key')];
51510 operation.title = t('operations.rotate.title');
51516 function operationSplit(selectedIDs, context) {
51517 var vertices = lodash.filter(selectedIDs, function(entityId) {
51518 return context.geometry(entityId) === 'vertex';
51521 var entityId = vertices[0],
51522 action = actionSplit(entityId);
51524 if (selectedIDs.length > 1) {
51525 action.limitWays(lodash.without(selectedIDs, entityId));
51529 var operation = function() {
51532 var ways = action.ways(context.graph());
51533 if (ways.length === 1) {
51534 annotation = t('operations.split.annotation.' + context.geometry(ways[0].id));
51536 annotation = t('operations.split.annotation.multiple', {n: ways.length});
51539 var difference = context.perform(action, annotation);
51540 context.enter(modeSelect(context, difference.extantIDs()));
51544 operation.available = function() {
51545 return vertices.length === 1;
51549 operation.disabled = function() {
51551 if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
51552 reason = 'connected_to_hidden';
51554 return action.disabled(context.graph()) || reason;
51558 operation.tooltip = function() {
51559 var disable = operation.disabled();
51561 return t('operations.split.' + disable);
51564 var ways = action.ways(context.graph());
51565 if (ways.length === 1) {
51566 return t('operations.split.description.' + context.geometry(ways[0].id));
51568 return t('operations.split.description.multiple');
51573 operation.id = 'split';
51574 operation.keys = [t('operations.split.key')];
51575 operation.title = t('operations.split.title');
51581 function operationStraighten(selectedIDs, context) {
51582 var entityId = selectedIDs[0],
51583 action = actionStraighten(entityId, context.projection);
51586 function operation() {
51587 var annotation = t('operations.straighten.annotation');
51588 context.perform(action, annotation);
51592 operation.available = function() {
51593 var entity = context.entity(entityId);
51594 return selectedIDs.length === 1 &&
51595 entity.type === 'way' &&
51596 !entity.isClosed() &&
51597 lodash.uniq(entity.nodes).length > 2;
51601 operation.disabled = function() {
51603 if (context.hasHiddenConnections(entityId)) {
51604 reason = 'connected_to_hidden';
51606 return action.disabled(context.graph()) || reason;
51610 operation.tooltip = function() {
51611 var disable = operation.disabled();
51613 t('operations.straighten.' + disable) :
51614 t('operations.straighten.description');
51618 operation.id = 'straighten';
51619 operation.keys = [t('operations.straighten.key')];
51620 operation.title = t('operations.straighten.title');
51628 var Operations = Object.freeze({
51629 operationCircularize: operationCircularize,
51630 operationContinue: operationContinue,
51631 operationDelete: operationDelete,
51632 operationDisconnect: operationDisconnect,
51633 operationMerge: operationMerge,
51634 operationMove: operationMove,
51635 operationOrthogonalize: operationOrthogonalize,
51636 operationReverse: operationReverse,
51637 operationRotate: operationRotate,
51638 operationSplit: operationSplit,
51639 operationStraighten: operationStraighten
51642 // Translate a MacOS key command into the appropriate Windows/Linux equivalent.
51643 // For example, ⌘Z -> Ctrl+Z
51644 function uiCmd(code) {
51645 var detected = utilDetect();
51647 if (detected.os === 'mac') {
51651 if (detected.os === 'win') {
51652 if (code === '⌘⇧Z') return 'Ctrl+Y';
51664 for (var i = 0; i < code.length; i++) {
51665 if (code[i] in replacements) {
51666 result += replacements[code[i]] + (i < code.length - 1 ? '+' : '');
51678 function modeSelect(context, selectedIDs) {
51684 var keybinding = d3keybinding('select'),
51687 behaviorCopy(context),
51688 behaviorPaste(context),
51689 behaviorBreathe(context),
51690 behaviorHover(context),
51691 behaviorSelect(context),
51692 behaviorLasso(context),
51693 modeDragNode$$1(context).selectedIDs(selectedIDs).behavior
51697 newFeature = false,
51698 suppressMenu = false,
51702 var wrap = context.container()
51703 .select('.inspector-wrap');
51706 function singular() {
51707 if (selectedIDs.length === 1) {
51708 return context.hasEntity(selectedIDs[0]);
51713 // find the common parent ways for nextVertex, previousVertex
51714 function commonParents() {
51715 var graph = context.graph(),
51716 commonParents = [];
51718 for (var i = 0; i < selectedIDs.length; i++) {
51719 var entity = context.hasEntity(selectedIDs[i]);
51720 if (!entity || entity.geometry(graph) !== 'vertex') {
51721 return []; // selection includes some not vertexes
51724 var currParents = lodash.map(graph.parentWays(entity), 'id');
51725 if (!commonParents.length) {
51726 commonParents = currParents;
51730 commonParents = lodash.intersection(commonParents, currParents);
51731 if (!commonParents.length) {
51736 return commonParents;
51740 function singularParent() {
51741 var parents = commonParents();
51743 relatedParent = null;
51747 // relatedParent is used when we visit a vertex with multiple
51748 // parents, and we want to remember which parent line we started on.
51750 if (parents.length === 1) {
51751 relatedParent = parents[0]; // remember this parent for later
51752 return relatedParent;
51755 if (parents.indexOf(relatedParent) !== -1) {
51756 return relatedParent; // prefer the previously seen parent
51763 function closeMenu() {
51765 context.surface().call(radialMenu.close);
51770 function positionMenu() {
51771 if (suppressMenu || !radialMenu) { return; }
51773 var entity = singular();
51774 if (entity && context.geometry(entity.id) === 'relation') {
51775 suppressMenu = true;
51776 } else if (entity && entity.type === 'node') {
51777 radialMenu.center(context.projection(entity.loc));
51779 var point = context.mouse(),
51780 viewport = geoExtent$$1(context.projection.clipExtent()).polygon();
51781 if (geoPointInPolygon(point, viewport)) {
51782 radialMenu.center(point);
51784 suppressMenu = true;
51790 function showMenu() {
51792 if (!suppressMenu && radialMenu) {
51793 context.surface().call(radialMenu);
51798 function toggleMenu() {
51799 if (select('.radial-menu').empty()) {
51807 mode.selectedIDs = function() {
51808 return selectedIDs;
51812 mode.reselect = function() {
51813 var surfaceNode = context.surface().node();
51814 if (surfaceNode.focus) { // FF doesn't support it
51815 surfaceNode.focus();
51823 mode.newFeature = function(_) {
51824 if (!arguments.length) return newFeature;
51830 mode.suppressMenu = function(_) {
51831 if (!arguments.length) return suppressMenu;
51837 mode.follow = function(_) {
51838 if (!arguments.length) return follow;
51844 mode.enter = function() {
51846 function update() {
51848 if (lodash.some(selectedIDs, function(id) { return !context.hasEntity(id); })) {
51849 // Exit mode if selected entity gets undone
51850 context.enter(modeBrowse$$1(context));
51855 function dblclick() {
51856 var target = select(event.target),
51857 datum = target.datum();
51859 if (datum instanceof osmWay && !target.classed('fill')) {
51860 var choice = geoChooseEdge(context.childNodes(datum), context.mouse(), context.projection),
51863 var prev = datum.nodes[choice.index - 1],
51864 next = datum.nodes[choice.index];
51867 actionAddMidpoint({loc: choice.loc, edge: [prev, next]}, node),
51868 t('operations.add.annotation.vertex')
51871 event.preventDefault();
51872 event.stopPropagation();
51877 function selectElements(drawn) {
51878 var surface = context.surface(),
51879 entity = singular();
51881 if (entity && context.geometry(entity.id) === 'relation') {
51882 suppressMenu = true;
51886 surface.selectAll('.related')
51887 .classed('related', false);
51890 if (relatedParent) {
51891 surface.selectAll(utilEntitySelector([relatedParent]))
51892 .classed('related', true);
51895 var selection$$1 = context.surface()
51896 .selectAll(utilEntityOrMemberSelector(selectedIDs, context.graph()));
51898 if (selection$$1.empty()) {
51899 // Return to browse mode if selected DOM elements have
51900 // disappeared because the user moved them out of view..
51901 var source = event && event.type === 'zoom' && event.sourceEvent;
51902 if (drawn && source && (source.type === 'mousemove' || source.type === 'touchmove')) {
51903 context.enter(modeBrowse$$1(context));
51907 .classed('selected', true);
51913 if (!context.inIntro()) {
51914 context.enter(modeBrowse$$1(context));
51919 function firstVertex() {
51920 event.preventDefault();
51921 var parent = singularParent();
51923 var way = context.entity(parent);
51925 modeSelect(context, [way.first()]).follow(true)
51931 function lastVertex() {
51932 event.preventDefault();
51933 var parent = singularParent();
51935 var way = context.entity(parent);
51937 modeSelect(context, [way.last()]).follow(true)
51943 function previousVertex() {
51944 event.preventDefault();
51945 var parent = singularParent();
51946 if (!parent) return;
51948 var way = context.entity(parent),
51949 length = way.nodes.length,
51950 curr = way.nodes.indexOf(selectedIDs[0]),
51955 } else if (way.isClosed()) {
51956 index = length - 2;
51959 if (index !== -1) {
51961 modeSelect(context, [way.nodes[index]]).follow(true)
51967 function nextVertex() {
51968 event.preventDefault();
51969 var parent = singularParent();
51970 if (!parent) return;
51972 var way = context.entity(parent),
51973 length = way.nodes.length,
51974 curr = way.nodes.indexOf(selectedIDs[0]),
51977 if (curr < length - 1) {
51979 } else if (way.isClosed()) {
51983 if (index !== -1) {
51985 modeSelect(context, [way.nodes[index]]).follow(true)
51991 function nextParent() {
51992 event.preventDefault();
51993 var parents = lodash.uniq(commonParents());
51994 if (!parents || parents.length < 2) return;
51996 var index = parents.indexOf(relatedParent);
51997 if (index < 0 || index > parents.length - 2) {
51998 relatedParent = parents[0];
52000 relatedParent = parents[index + 1];
52003 var surface = context.surface();
52004 surface.selectAll('.related')
52005 .classed('related', false);
52007 if (relatedParent) {
52008 surface.selectAll(utilEntitySelector([relatedParent]))
52009 .classed('related', true);
52014 behaviors.forEach(function(behavior) {
52015 context.install(behavior);
52018 var operations = lodash.without(values(Operations), operationDelete)
52019 .map(function(o) { return o(selectedIDs, context); })
52020 .filter(function(o) { return o.available(); });
52022 operations.unshift(operationDelete(selectedIDs, context));
52025 .on(['[','pgup'], previousVertex)
52026 .on([']', 'pgdown'], nextVertex)
52027 .on([uiCmd('⌘['), 'home'], firstVertex)
52028 .on([uiCmd('⌘]'), 'end'], lastVertex)
52029 .on(['\\', 'pause'], nextParent)
52030 .on('⎋', esc, true)
52031 .on('space', toggleMenu);
52033 operations.forEach(function(operation) {
52034 operation.keys.forEach(function(key) {
52035 keybinding.on(key, function() {
52036 if (!(context.inIntro() || operation.disabled())) {
52046 radialMenu = uiRadialMenu(context, operations);
52048 context.ui().sidebar
52049 .select(singular() ? singular().id : null, newFeature);
52052 .on('undone.select', update)
52053 .on('redone.select', update);
52056 .on('move.select', closeMenu)
52057 .on('drawn.select', selectElements);
52061 var show = event && !suppressMenu;
52068 var extent$$1 = geoExtent$$1(),
52069 graph = context.graph();
52070 selectedIDs.forEach(function(id) {
52071 var entity = context.entity(id);
52072 extent$$1._extend(entity.extent(graph));
52075 var loc = extent$$1.center();
52076 context.map().centerEase(loc);
52079 timeout$$1 = window.setTimeout(function() {
52085 .on('dblclick.select', dblclick);
52088 if (selectedIDs.length > 1) {
52089 var entities = uiSelectionList(context, selectedIDs);
52090 context.ui().sidebar.show(entities);
52095 mode.exit = function() {
52096 if (timeout$$1) window.clearTimeout(timeout$$1);
52098 if (inspector) wrap.call(inspector.close);
52100 behaviors.forEach(function(behavior) {
52101 context.uninstall(behavior);
52106 radialMenu = undefined;
52109 .on('undone.select', null)
52110 .on('redone.select', null);
52112 var surface = context.surface();
52115 .on('dblclick.select', null);
52118 .selectAll('.selected')
52119 .classed('selected', false);
52122 .selectAll('.related')
52123 .classed('related', false);
52125 context.map().on('drawn.select', null);
52126 context.ui().sidebar.hide();
52133 function uiAccount(context) {
52134 var connection = context.connection();
52137 function update(selection$$1) {
52138 if (!connection.authenticated()) {
52139 selection$$1.selectAll('#userLink, #logoutLink')
52140 .classed('hide', true);
52144 connection.userDetails(function(err, details) {
52145 var userLink = selection$$1.select('#userLink'),
52146 logoutLink = selection$$1.select('#logoutLink');
52149 logoutLink.html('');
52153 selection$$1.selectAll('#userLink, #logoutLink')
52154 .classed('hide', false);
52157 userLink.append('a')
52158 .attr('href', connection.userURL(details.display_name))
52159 .attr('target', '_blank');
52161 // Add thumbnail or dont
52162 if (details.image_url) {
52163 userLink.append('img')
52164 .attr('class', 'icon pre-text user-icon')
52165 .attr('src', details.image_url);
52168 .call(svgIcon('#icon-avatar', 'pre-text light'));
52172 userLink.append('span')
52173 .attr('class', 'label')
52174 .text(details.display_name);
52176 logoutLink.append('a')
52177 .attr('class', 'logout')
52180 .on('click.logout', function() {
52181 event.preventDefault();
52182 connection.logout();
52188 return function(selection$$1) {
52189 selection$$1.append('li')
52190 .attr('id', 'logoutLink')
52191 .classed('hide', true);
52193 selection$$1.append('li')
52194 .attr('id', 'userLink')
52195 .classed('hide', true);
52198 .on('change.account', function() { update(selection$$1); });
52200 update(selection$$1);
52204 function uiAttribution(context) {
52208 function attribution(data, klass) {
52209 var div = selection$$1.selectAll('.' + klass)
52214 .attr('class', klass)
52218 var background = div.selectAll('.attribution')
52219 .data(data, function(d) { return d.name(); });
52224 background = background.enter()
52226 .attr('class', 'attribution')
52227 .each(function(d) {
52228 if (d.terms_html) {
52230 .html(d.terms_html);
52234 var source = d.terms_text || d.id || d.name();
52237 source = '<img class="source-image" src="' + context.imagePath(d.logo) + '">';
52243 .attr('href', d.terms_url)
52244 .attr('target', '_blank')
52251 .merge(background);
52254 var copyright = background.selectAll('.copyright-notice')
52255 .data(function(d) {
52256 var notice = d.copyrightNotices(context.map().zoom(), context.map().extent());
52257 return notice ? [notice] : [];
52263 copyright = copyright.enter()
52265 .attr('class', 'copyright-notice')
52273 function update() {
52274 attribution([context.background().baseLayerSource()], 'base-layer-attribution');
52275 attribution(context.background().overlayLayerSources().filter(function (s) {
52276 return s.validZoom(context.map().zoom());
52277 }), 'overlay-layer-attribution');
52281 return function(select$$1) {
52282 selection$$1 = select$$1;
52284 context.background()
52285 .on('change.attribution', update);
52288 .on('move.attribution', lodash.throttle(update, 400, {leading: false}));
52294 function rendererBackgroundSource(data) {
52295 var source = lodash.clone(data),
52297 name = source.name,
52298 best = !!source.best;
52300 source.scaleExtent = data.scaleExtent || [0, 20];
52301 source.overzoom = data.overzoom !== false;
52304 source.offset = function(_) {
52305 if (!arguments.length) return offset;
52311 source.nudge = function(_, zoomlevel) {
52312 offset[0] += _[0] / Math.pow(2, zoomlevel);
52313 offset[1] += _[1] / Math.pow(2, zoomlevel);
52318 source.name = function() {
52323 source.best = function() {
52328 source.area = function() {
52329 if (!data.polygon) return Number.MAX_VALUE; // worldwide
52330 var area$$1 = area$1({ type: 'MultiPolygon', coordinates: [ data.polygon ] });
52331 return isNaN(area$$1) ? 0 : area$$1;
52335 source.imageryUsed = function() {
52336 return name || source.id;
52340 source.url = function(coord) {
52341 return data.template
52342 .replace('{x}', coord[0])
52343 .replace('{y}', coord[1])
52344 // TMS-flipped y coordinate
52345 .replace(/\{[t-]y\}/, Math.pow(2, coord[2]) - coord[1] - 1)
52346 .replace(/\{z(oom)?\}/, coord[2])
52347 .replace(/\{switch:([^}]+)\}/, function(s, r) {
52348 var subdomains = r.split(',');
52349 return subdomains[(coord[0] + coord[1]) % subdomains.length];
52351 .replace('{u}', function() {
52353 for (var zoom$$1 = coord[2]; zoom$$1 > 0; zoom$$1--) {
52355 var mask = 1 << (zoom$$1 - 1);
52356 if ((coord[0] & mask) !== 0) b++;
52357 if ((coord[1] & mask) !== 0) b += 2;
52365 source.intersects = function(extent$$1) {
52366 extent$$1 = extent$$1.polygon();
52367 return !data.polygon || data.polygon.some(function(polygon) {
52368 return geoPolygonIntersectsPolygon(polygon, extent$$1, true);
52373 source.validZoom = function(z) {
52374 return source.scaleExtent[0] <= z &&
52375 (source.overzoom || source.scaleExtent[1] > z);
52379 source.isLocatorOverlay = function() {
52380 return source.id === 'mapbox_locator_overlay';
52384 source.copyrightNotices = function() {};
52391 rendererBackgroundSource.Bing = function(data, dispatch$$1) {
52392 // http://msdn.microsoft.com/en-us/library/ff701716.aspx
52393 // http://msdn.microsoft.com/en-us/library/ff701701.aspx
52395 data.template = 'https://ecn.t{switch:0,1,2,3}.tiles.virtualearth.net/tiles/a{u}.jpeg?g=587&mkt=en-gb&n=z';
52397 var bing = rendererBackgroundSource(data),
52398 key = 'Arzdiw4nlOJzRwOz__qailc8NiR31Tt51dN2D7cm57NrnceZnCpgOkmJhNpGoppU', // Same as P2 and JOSM
52399 url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?include=ImageryProviders&key=' +
52400 key + '&jsonp={callback}',
52403 jsonpRequest(url, function(json$$1) {
52404 providers = json$$1.resourceSets[0].resources[0].imageryProviders.map(function(provider) {
52406 attribution: provider.attribution,
52407 areas: provider.coverageAreas.map(function(area$$1) {
52409 zoom: [area$$1.zoomMin, area$$1.zoomMax],
52410 extent: geoExtent$$1([area$$1.bbox[1], area$$1.bbox[0]], [area$$1.bbox[3], area$$1.bbox[2]])
52415 dispatch$$1.call('change');
52418 bing.copyrightNotices = function(zoom$$1, extent$$1) {
52419 zoom$$1 = Math.min(zoom$$1, 21);
52420 return providers.filter(function(provider) {
52421 return lodash.some(provider.areas, function(area$$1) {
52422 return extent$$1.intersects(area$$1.extent) &&
52423 area$$1.zoom[0] <= zoom$$1 &&
52424 area$$1.zoom[1] >= zoom$$1;
52426 }).map(function(provider) {
52427 return provider.attribution;
52431 bing.logo = 'bing_maps.png';
52432 bing.terms_url = 'https://blog.openstreetmap.org/2010/11/30/microsoft-imagery-details';
52438 rendererBackgroundSource.None = function() {
52439 var source = rendererBackgroundSource({ id: 'none', template: '' });
52441 source.name = function() {
52442 return t('background.none');
52445 source.imageryUsed = function() {
52449 source.area = function() {
52450 return -1; // sources in background pane are sorted by area
52457 rendererBackgroundSource.Custom = function(template) {
52458 var source = rendererBackgroundSource({ id: 'custom', template: template });
52460 source.name = function() {
52461 return t('background.custom');
52464 source.imageryUsed = function() {
52465 return 'Custom (' + template + ')';
52468 source.area = function() {
52469 return -2; // sources in background pane are sorted by area
52475 function rendererTileLayer(context) {
52476 var tileSize = 256,
52477 tile = d3geoTile(),
52482 transformProp = utilPrefixCSSProperty('Transform'),
52483 source = rendererBackgroundSource.None();
52486 // blacklist overlay tiles around Null Island..
52487 function nearNullIsland(x, y, z) {
52489 var center = Math.pow(2, z - 1),
52490 width = Math.pow(2, z - 6),
52491 min$$1 = center - (width / 2),
52492 max$$1 = center + (width / 2) - 1;
52493 return x >= min$$1 && x <= max$$1 && y >= min$$1 && y <= max$$1;
52499 function tileSizeAtZoom(d, z) {
52500 var epsilon = 0.002;
52501 return ((tileSize * Math.pow(2, z - d[2])) / tileSize) + epsilon;
52505 function atZoom(t, distance) {
52506 var power = Math.pow(2, distance);
52508 Math.floor(t[0] * power),
52509 Math.floor(t[1] * power),
52514 function lookUp(d) {
52515 for (var up = -1; up > -d[2]; up--) {
52516 var tile = atZoom(d, up);
52517 if (cache[source.url(tile)] !== false) {
52524 function uniqueBy(a, n) {
52525 var o = [], seen = {};
52526 for (var i = 0; i < a.length; i++) {
52527 if (seen[a[i][n]] === undefined) {
52529 seen[a[i][n]] = true;
52536 function addSource(d) {
52537 d.push(source.url(d));
52542 // Update tiles based on current state of `projection`.
52543 function background(selection$$1) {
52544 tile.scale(projection.scale() * 2 * Math.PI)
52545 .translate(projection.translate());
52548 projection.scale() * Math.PI - projection.translate()[0],
52549 projection.scale() * Math.PI - projection.translate()[1]];
52551 z = Math.max(Math.log(projection.scale() * 2 * Math.PI) / Math.log(2) - 8, 0);
52553 render(selection$$1);
52557 // Derive the tiles onscreen, remove those offscreen and position them.
52558 // Important that this part not depend on `projection` because it's
52559 // rentered when tiles load/error (see #644).
52560 function render(selection$$1) {
52562 var showDebug = context.getDebug('tile') && !source.overlay;
52564 if (source.validZoom(z)) {
52565 tile().forEach(function(d) {
52567 if (d[3] === '') return;
52568 if (typeof d[3] !== 'string') return; // Workaround for chrome crash https://github.com/openstreetmap/iD/issues/2295
52570 if (cache[d[3]] === false && lookUp(d)) {
52571 requests.push(addSource(lookUp(d)));
52575 requests = uniqueBy(requests, 3).filter(function(r) {
52576 if (!!source.overlay && nearNullIsland(r[0], r[1], r[2])) {
52579 // don't re-request tiles which have failed in the past
52580 return cache[r[3]] !== false;
52584 var pixelOffset = [
52585 source.offset()[0] * Math.pow(2, z),
52586 source.offset()[1] * Math.pow(2, z)
52590 cache[d[3]] = true;
52594 .classed('tile-loaded', true);
52595 render(selection$$1);
52598 function error(d) {
52599 cache[d[3]] = false;
52604 render(selection$$1);
52607 function imageTransform(d) {
52608 var _ts = tileSize * Math.pow(2, z - d[2]);
52609 var scale = tileSizeAtZoom(d, z);
52610 return 'translate(' +
52611 ((d[0] * _ts) - tileOrigin[0] + pixelOffset[0]) + 'px,' +
52612 ((d[1] * _ts) - tileOrigin[1] + pixelOffset[1]) + 'px)' +
52613 'scale(' + scale + ',' + scale + ')';
52616 function debugTransform(d) {
52617 var _ts = tileSize * Math.pow(2, z - d[2]);
52618 var scale = tileSizeAtZoom(d, z);
52619 return 'translate(' +
52620 ((d[0] * _ts) - tileOrigin[0] + pixelOffset[0] + scale * (tileSize / 4)) + 'px,' +
52621 ((d[1] * _ts) - tileOrigin[1] + pixelOffset[1] + scale * (tileSize / 2)) + 'px)';
52625 var image = selection$$1.selectAll('img')
52626 .data(requests, function(d) { return d[3]; });
52629 .style(transformProp, imageTransform)
52630 .classed('tile-removing', true)
52632 var tile = select(this);
52633 window.setTimeout(function() {
52634 if (tile.classed('tile-removing')) {
52642 .attr('class', 'tile')
52643 .attr('src', function(d) { return d[3]; })
52644 .on('error', error)
52647 .style(transformProp, imageTransform)
52648 .classed('tile-debug', showDebug)
52649 .classed('tile-removing', false);
52652 var debug = selection$$1.selectAll('.tile-label-debug')
52653 .data(showDebug ? requests : [], function(d) { return d[3]; });
52660 .attr('class', 'tile-label-debug')
52662 .text(function(d) { return d[2] + ' / ' + d[0] + ' / ' + d[1]; })
52663 .style(transformProp, debugTransform);
52667 background.projection = function(_) {
52668 if (!arguments.length) return projection;
52674 background.dimensions = function(_) {
52675 if (!arguments.length) return tile.size();
52681 background.source = function(_) {
52682 if (!arguments.length) return source;
52685 tile.scaleExtent(source.scaleExtent);
52693 function rendererBackground(context) {
52694 var dispatch$$1 = dispatch('change'),
52695 baseLayer = rendererTileLayer(context).projection(context.projection),
52696 overlayLayers = [],
52700 function findSource(id) {
52701 return lodash.find(backgroundSources, function(d) {
52702 return d.id && d.id === id;
52707 function background(selection$$1) {
52708 var base = selection$$1.selectAll('.layer-background')
52712 .insert('div', '.layer-data')
52713 .attr('class', 'layer layer-background')
52717 var overlays = selection$$1.selectAll('.layer-overlay')
52718 .data(overlayLayers, function(d) { return d.source().name(); });
52724 .insert('div', '.layer-data')
52725 .attr('class', 'layer layer-overlay')
52727 .each(function(layer) { select(this).call(layer); });
52731 background.updateImagery = function() {
52732 var b = background.baseLayerSource(),
52734 .filter(function (d) { return !d.source().isLocatorOverlay(); })
52735 .map(function (d) { return d.source().id; })
52737 meters = geoOffsetToMeters(b.offset()),
52739 x = +meters[0].toFixed(2),
52740 y = +meters[1].toFixed(2),
52741 q = utilStringQs(window.location.hash.substring(1));
52744 if (id === 'custom') {
52745 id = 'custom:' + b.template;
52751 delete q.background;
52760 if (Math.abs(x) > epsilon || Math.abs(y) > epsilon) {
52761 q.offset = x + ',' + y;
52766 window.location.replace('#' + utilQsString(q, true));
52768 var imageryUsed = [b.imageryUsed()];
52771 .filter(function (d) { return !d.source().isLocatorOverlay(); })
52772 .forEach(function (d) { imageryUsed.push(d.source().imageryUsed()); });
52774 var gpx = context.layers().layer('gpx');
52775 if (gpx && gpx.enabled() && gpx.hasGpx()) {
52776 imageryUsed.push('Local GPX');
52779 var mapillary_images = context.layers().layer('mapillary-images');
52780 if (mapillary_images && mapillary_images.enabled()) {
52781 imageryUsed.push('Mapillary Images');
52784 var mapillary_signs = context.layers().layer('mapillary-signs');
52785 if (mapillary_signs && mapillary_signs.enabled()) {
52786 imageryUsed.push('Mapillary Signs');
52789 context.history().imageryUsed(imageryUsed);
52793 background.sources = function(extent$$1) {
52794 return backgroundSources.filter(function(source) {
52795 return source.intersects(extent$$1);
52800 background.dimensions = function(_) {
52802 baseLayer.dimensions(_);
52804 overlayLayers.forEach(function(layer) {
52805 layer.dimensions(_);
52810 background.baseLayerSource = function(d) {
52811 if (!arguments.length) return baseLayer.source();
52812 baseLayer.source(d);
52813 dispatch$$1.call('change');
52814 background.updateImagery();
52819 background.bing = function() {
52820 background.baseLayerSource(findSource('Bing'));
52824 background.showsLayer = function(d) {
52825 return d === baseLayer.source() ||
52826 (d.id === 'custom' && baseLayer.source().id === 'custom') ||
52827 overlayLayers.some(function(l) { return l.source() === d; });
52831 background.overlayLayerSources = function() {
52832 return overlayLayers.map(function (l) { return l.source(); });
52836 background.toggleOverlayLayer = function(d) {
52839 for (var i = 0; i < overlayLayers.length; i++) {
52840 layer = overlayLayers[i];
52841 if (layer.source() === d) {
52842 overlayLayers.splice(i, 1);
52843 dispatch$$1.call('change');
52844 background.updateImagery();
52849 layer = rendererTileLayer(context)
52851 .projection(context.projection)
52852 .dimensions(baseLayer.dimensions());
52854 overlayLayers.push(layer);
52855 dispatch$$1.call('change');
52856 background.updateImagery();
52860 background.nudge = function(d, zoom$$1) {
52861 baseLayer.source().nudge(d, zoom$$1);
52862 dispatch$$1.call('change');
52863 background.updateImagery();
52868 background.offset = function(d) {
52869 if (!arguments.length) return baseLayer.source().offset();
52870 baseLayer.source().offset(d);
52871 dispatch$$1.call('change');
52872 background.updateImagery();
52877 background.init = function() {
52878 function parseMap(qmap) {
52879 if (!qmap) return false;
52880 var args = qmap.split('/').map(Number);
52881 if (args.length < 3 || args.some(isNaN)) return false;
52882 return geoExtent$$1([args[2], args[1]]);
52885 var dataImagery = data.imagery || [],
52886 q = utilStringQs(window.location.hash.substring(1)),
52887 chosen = q.background || q.layer,
52888 extent$$1 = parseMap(q.map),
52891 backgroundSources = dataImagery.map(function(source) {
52892 if (source.type === 'bing') {
52893 return rendererBackgroundSource.Bing(source, dispatch$$1);
52895 return rendererBackgroundSource(source);
52899 backgroundSources.unshift(rendererBackgroundSource.None());
52901 if (!chosen && extent$$1) {
52902 best = lodash.find(this.sources(extent$$1), function(s) { return s.best(); });
52905 if (chosen && chosen.indexOf('custom:') === 0) {
52906 background.baseLayerSource(rendererBackgroundSource.Custom(chosen.replace(/^custom:/, '')));
52908 background.baseLayerSource(findSource(chosen) || best || findSource('Bing') || backgroundSources[1] || backgroundSources[0]);
52911 var locator = lodash.find(backgroundSources, function(d) {
52912 return d.overlay && d.default;
52916 background.toggleOverlayLayer(locator);
52919 var overlays = (q.overlays || '').split(',');
52920 overlays.forEach(function(overlay) {
52921 overlay = findSource(overlay);
52923 background.toggleOverlayLayer(overlay);
52928 var gpx = context.layers().layer('gpx');
52935 var offset = q.offset.replace(/;/g, ',').split(',').map(function(n) {
52936 return !isNaN(n) && n;
52939 if (offset.length === 2) {
52940 background.offset(geoMetersToOffset(offset));
52946 return utilRebind(background, dispatch$$1, 'on');
52949 function rendererFeatures(context) {
52950 var traffic_roads = {
52952 'motorway_link': true,
52954 'trunk_link': true,
52956 'primary_link': true,
52958 'secondary_link': true,
52960 'tertiary_link': true,
52961 'residential': true,
52962 'unclassified': true,
52963 'living_street': true
52966 var service_roads = {
52978 'pedestrian': true,
52982 var past_futures = {
52984 'construction': true,
52986 'dismantled': true,
52989 'demolished': true,
52990 'obliterated': true
52993 var dispatch$$1 = dispatch('change', 'redraw'),
53002 function update() {
53003 _hidden = features.hidden();
53004 dispatch$$1.call('change');
53005 dispatch$$1.call('redraw');
53009 function defineFeature(k, filter, max$$1) {
53013 enabled: true, // whether the user wants it enabled..
53015 currentMax: (max$$1 || Infinity),
53016 defaultMax: (max$$1 || Infinity),
53017 enable: function() { this.enabled = true; this.currentMax = this.defaultMax; },
53018 disable: function() { this.enabled = false; this.currentMax = 0; },
53019 hidden: function() { return !context.editable() || this.count > this.currentMax * _cullFactor; },
53020 autoHidden: function() { return this.hidden() && this.currentMax > 0; }
53025 defineFeature('points', function isPoint(entity, resolver, geometry) {
53026 return geometry === 'point';
53029 defineFeature('traffic_roads', function isTrafficRoad(entity) {
53030 return traffic_roads[entity.tags.highway];
53033 defineFeature('service_roads', function isServiceRoad(entity) {
53034 return service_roads[entity.tags.highway];
53037 defineFeature('paths', function isPath(entity) {
53038 return paths[entity.tags.highway];
53041 defineFeature('buildings', function isBuilding(entity) {
53043 !!entity.tags['building:part'] ||
53044 (!!entity.tags.building && entity.tags.building !== 'no') ||
53045 entity.tags.amenity === 'shelter' ||
53046 entity.tags.parking === 'multi-storey' ||
53047 entity.tags.parking === 'sheds' ||
53048 entity.tags.parking === 'carports' ||
53049 entity.tags.parking === 'garage_boxes'
53053 defineFeature('landuse', function isLanduse(entity, resolver, geometry) {
53054 return geometry === 'area' &&
53055 !_features.buildings.filter(entity) &&
53056 !_features.water.filter(entity);
53059 defineFeature('boundaries', function isBoundary(entity) {
53060 return !!entity.tags.boundary;
53063 defineFeature('water', function isWater(entity) {
53065 !!entity.tags.waterway ||
53066 entity.tags.natural === 'water' ||
53067 entity.tags.natural === 'coastline' ||
53068 entity.tags.natural === 'bay' ||
53069 entity.tags.landuse === 'pond' ||
53070 entity.tags.landuse === 'basin' ||
53071 entity.tags.landuse === 'reservoir' ||
53072 entity.tags.landuse === 'salt_pond'
53076 defineFeature('rail', function isRail(entity) {
53078 !!entity.tags.railway ||
53079 entity.tags.landuse === 'railway'
53081 traffic_roads[entity.tags.highway] ||
53082 service_roads[entity.tags.highway] ||
53083 paths[entity.tags.highway]
53087 defineFeature('power', function isPower(entity) {
53088 return !!entity.tags.power;
53091 // contains a past/future tag, but not in active use as a road/path/cycleway/etc..
53092 defineFeature('past_future', function isPastFuture(entity) {
53094 traffic_roads[entity.tags.highway] ||
53095 service_roads[entity.tags.highway] ||
53096 paths[entity.tags.highway]
53097 ) { return false; }
53099 var strings = Object.keys(entity.tags);
53101 for (var i = 0; i < strings.length; i++) {
53102 var s = strings[i];
53103 if (past_futures[s] || past_futures[entity.tags[s]]) { return true; }
53108 // Lines or areas that don't match another feature filter.
53109 // IMPORTANT: The 'others' feature must be the last one defined,
53110 // so that code in getMatches can skip this test if `hasMatch = true`
53111 defineFeature('others', function isOther(entity, resolver, geometry) {
53112 return (geometry === 'line' || geometry === 'area');
53116 function features() {}
53119 features.features = function() {
53124 features.keys = function() {
53129 features.enabled = function(k) {
53130 if (!arguments.length) {
53131 return _keys.filter(function(k) { return _features[k].enabled; });
53133 return _features[k] && _features[k].enabled;
53137 features.disabled = function(k) {
53138 if (!arguments.length) {
53139 return _keys.filter(function(k) { return !_features[k].enabled; });
53141 return _features[k] && !_features[k].enabled;
53145 features.hidden = function(k) {
53146 if (!arguments.length) {
53147 return _keys.filter(function(k) { return _features[k].hidden(); });
53149 return _features[k] && _features[k].hidden();
53153 features.autoHidden = function(k) {
53154 if (!arguments.length) {
53155 return _keys.filter(function(k) { return _features[k].autoHidden(); });
53157 return _features[k] && _features[k].autoHidden();
53161 features.enable = function(k) {
53162 if (_features[k] && !_features[k].enabled) {
53163 _features[k].enable();
53169 features.disable = function(k) {
53170 if (_features[k] && _features[k].enabled) {
53171 _features[k].disable();
53177 features.toggle = function(k) {
53178 if (_features[k]) {
53179 (function(f) { return f.enabled ? f.disable() : f.enable(); }(_features[k]));
53185 features.resetStats = function() {
53186 for (var i = 0; i < _keys.length; i++) {
53187 _features[_keys[i]].count = 0;
53189 dispatch$$1.call('change');
53193 features.gatherStats = function(d, resolver, dimensions) {
53194 var needsRedraw = false,
53195 type = lodash.groupBy(d, function(ent) { return ent.type; }),
53196 entities = [].concat(type.relation || [], type.way || [], type.node || []),
53197 currHidden, geometry, matches, i, j;
53199 for (i = 0; i < _keys.length; i++) {
53200 _features[_keys[i]].count = 0;
53203 // adjust the threshold for point/building culling based on viewport size..
53204 // a _cullFactor of 1 corresponds to a 1000x1000px viewport..
53205 _cullFactor = dimensions[0] * dimensions[1] / 1000000;
53207 for (i = 0; i < entities.length; i++) {
53208 geometry = entities[i].geometry(resolver);
53209 if (!(geometry === 'vertex' || geometry === 'relation')) {
53210 matches = Object.keys(features.getMatches(entities[i], resolver, geometry));
53211 for (j = 0; j < matches.length; j++) {
53212 _features[matches[j]].count++;
53217 currHidden = features.hidden();
53218 if (currHidden !== _hidden) {
53219 _hidden = currHidden;
53220 needsRedraw = true;
53221 dispatch$$1.call('change');
53224 return needsRedraw;
53228 features.stats = function() {
53229 for (var i = 0; i < _keys.length; i++) {
53230 _stats[_keys[i]] = _features[_keys[i]].count;
53237 features.clear = function(d) {
53238 for (var i = 0; i < d.length; i++) {
53239 features.clearEntity(d[i]);
53244 features.clearEntity = function(entity) {
53245 delete _cache[osmEntity$$1.key(entity)];
53249 features.reset = function() {
53254 features.getMatches = function(entity, resolver, geometry) {
53255 if (geometry === 'vertex' || geometry === 'relation') return {};
53257 var ent = osmEntity$$1.key(entity);
53258 if (!_cache[ent]) {
53262 if (!_cache[ent].matches) {
53266 for (var i = 0; i < _keys.length; i++) {
53267 if (_keys[i] === 'others') {
53268 if (hasMatch) continue;
53270 // Multipolygon members:
53272 // 1. is a way that hasn't matched other 'interesting' feature rules,
53273 // 2. and it belongs to a single parent multipolygon relation
53274 // ...then match whatever feature rules the parent multipolygon has matched.
53275 // see #2548, #2887
53278 // For this to work, getMatches must be called on relations before ways.
53280 if (entity.type === 'way') {
53281 var parents = features.getParents(entity, resolver, geometry);
53282 if (parents.length === 1 && parents[0].isMultipolygon()) {
53283 var pkey = osmEntity$$1.key(parents[0]);
53284 if (_cache[pkey] && _cache[pkey].matches) {
53285 matches = lodash.clone(_cache[pkey].matches);
53292 if (_features[_keys[i]].filter(entity, resolver, geometry)) {
53293 matches[_keys[i]] = hasMatch = true;
53296 _cache[ent].matches = matches;
53299 return _cache[ent].matches;
53303 features.getParents = function(entity, resolver, geometry) {
53304 if (geometry === 'point') return [];
53306 var ent = osmEntity$$1.key(entity);
53307 if (!_cache[ent]) {
53311 if (!_cache[ent].parents) {
53313 if (geometry === 'vertex') {
53314 parents = resolver.parentWays(entity);
53315 } else { // 'line', 'area', 'relation'
53316 parents = resolver.parentRelations(entity);
53318 _cache[ent].parents = parents;
53320 return _cache[ent].parents;
53324 features.isHiddenFeature = function(entity, resolver, geometry) {
53325 if (!_hidden.length) return false;
53326 if (!entity.version) return false;
53328 var matches = features.getMatches(entity, resolver, geometry);
53330 for (var i = 0; i < _hidden.length; i++) {
53331 if (matches[_hidden[i]]) return true;
53337 features.isHiddenChild = function(entity, resolver, geometry) {
53338 if (!_hidden.length) return false;
53339 if (!entity.version || geometry === 'point') return false;
53341 var parents = features.getParents(entity, resolver, geometry);
53342 if (!parents.length) return false;
53344 for (var i = 0; i < parents.length; i++) {
53345 if (!features.isHidden(parents[i], resolver, parents[i].geometry(resolver))) {
53353 features.hasHiddenConnections = function(entity, resolver) {
53354 if (!_hidden.length) return false;
53355 var childNodes, connections;
53357 if (entity.type === 'midpoint') {
53358 childNodes = [resolver.entity(entity.edge[0]), resolver.entity(entity.edge[1])];
53361 childNodes = entity.nodes ? resolver.childNodes(entity) : [];
53362 connections = features.getParents(entity, resolver, entity.geometry(resolver));
53365 // gather ways connected to child nodes..
53366 connections = lodash.reduce(childNodes, function(result, e) {
53367 return resolver.isShared(e) ? lodash.union(result, resolver.parentWays(e)) : result;
53370 return connections.length ? lodash.some(connections, function(e) {
53371 return features.isHidden(e, resolver, e.geometry(resolver));
53376 features.isHidden = function(entity, resolver, geometry) {
53377 if (!_hidden.length) return false;
53378 if (!entity.version) return false;
53380 var fn = (geometry === 'vertex' ? features.isHiddenChild : features.isHiddenFeature);
53381 return fn(entity, resolver, geometry);
53385 features.filter = function(d, resolver) {
53386 if (!_hidden.length) return d;
53389 for (var i = 0; i < d.length; i++) {
53391 if (!features.isHidden(entity, resolver, entity.geometry(resolver))) {
53392 result.push(entity);
53399 return utilRebind(features, dispatch$$1, 'on');
53402 function utilBindOnce(target, type, listener, capture) {
53403 var typeOnce = type + '.once';
53405 target.on(typeOnce, null);
53406 listener.apply(this, arguments);
53408 target.on(typeOnce, one, capture);
53412 function rendererMap(context) {
53414 var dimensions = [1, 1],
53415 dispatch$$1 = dispatch('move', 'drawn'),
53416 projection = context.projection,
53417 dblclickEnabled = true,
53418 redrawEnabled = true,
53419 transformStart = projection.transform(),
53420 transformed = false,
53422 drawLayers = svgLayers(projection, context),
53423 drawPoints = svgPoints$$1(projection, context),
53424 drawVertices = svgVertices$$1(projection, context),
53425 drawLines = svgLines$$1(projection),
53426 drawAreas = svgAreas$$1(projection, context),
53427 drawMidpoints = svgMidpoints$$1(projection, context),
53428 drawLabels = svgLabels(projection, context),
53435 var zoom$$1 = zoom()
53436 .scaleExtent([ztok(2), ztok(24)]) // TODO: uncomment interpolate when d3.zoom 1.0.4 avail:
53437 // .interpolate(d3.interpolate) // https://github.com/d3/d3-zoom/issues/54
53438 .on('zoom', zoomPan); // default zoom interpolator does a fly-out-in
53440 var _selection = select(null);
53443 function map$$1(selection$$1) {
53445 _selection = selection$$1;
53448 .on('change.map', immediateRedraw);
53449 context.connection()
53450 .on('change.map', immediateRedraw);
53452 .on('change.map', immediateRedraw);
53453 context.background()
53454 .on('change.map', immediateRedraw);
53456 .on('redraw.map', immediateRedraw);
53458 .on('change.map', function() {
53459 context.background().updateImagery();
53464 .on('dblclick.map', dblClick)
53465 .call(zoom$$1, projection.transform());
53467 supersurface = selection$$1.append('div')
53468 .attr('id', 'supersurface')
53469 .call(utilSetTransform, 0, 0);
53471 // Need a wrapper div because Opera can't cope with an absolutely positioned
53472 // SVG element: http://bl.ocks.org/jfirebaugh/6fbfbd922552bf776c16
53473 wrapper = supersurface
53475 .attr('class', 'layer layer-data');
53477 map$$1.surface = surface = wrapper
53479 .selectAll('.surface')
53480 .attr('id', 'surface');
53483 .call(drawLabels.observe)
53484 .on('mousedown.zoom', function() {
53485 if (event.button === 2) {
53486 event.stopPropagation();
53489 .on('mouseup.zoom', function() {
53490 if (resetTransform()) immediateRedraw();
53492 .on('mousemove.map', function() {
53495 .on('mouseover.vertices', function() {
53496 if (map$$1.editable() && !transformed) {
53497 var hover = event.target.__data__;
53498 surface.selectAll('.data-layer-osm')
53499 .call(drawVertices.drawHover, context.graph(), hover, map$$1.extent(), map$$1.zoom());
53500 dispatch$$1.call('drawn', this, {full: false});
53503 .on('mouseout.vertices', function() {
53504 if (map$$1.editable() && !transformed) {
53505 var hover = event.relatedTarget && event.relatedTarget.__data__;
53506 surface.selectAll('.data-layer-osm')
53507 .call(drawVertices.drawHover, context.graph(), hover, map$$1.extent(), map$$1.zoom());
53508 dispatch$$1.call('drawn', this, {full: false});
53513 .call(context.background());
53515 context.on('enter.map', function() {
53516 if (map$$1.editable() && !transformed) {
53517 var all = context.intersects(map$$1.extent()),
53518 filter = utilFunctor(true),
53519 graph = context.graph();
53521 all = context.features().filter(all, graph);
53522 surface.selectAll('.data-layer-osm')
53523 .call(drawVertices, graph, all, filter, map$$1.extent(), map$$1.zoom())
53524 .call(drawMidpoints, graph, all, filter, map$$1.trimmedExtent());
53525 dispatch$$1.call('drawn', this, {full: false});
53529 map$$1.dimensions(utilGetDimensions(selection$$1));
53535 return 256 * Math.pow(2, z);
53539 return Math.max(Math.log(k) / Math.LN2 - 8, 0);
53542 function pxCenter() {
53543 return [dimensions[0] / 2, dimensions[1] / 2];
53547 function drawVector(difference, extent$$1) {
53548 var graph = context.graph(),
53549 features = context.features(),
53550 all = context.intersects(map$$1.extent()),
53554 var complete = difference.complete(map$$1.extent());
53555 data = lodash.compact(lodash.values(complete));
53556 filter = function(d) { return d.id in complete; };
53557 features.clear(data);
53560 // force a full redraw if gatherStats detects that a feature
53561 // should be auto-hidden (e.g. points or buildings)..
53562 if (features.gatherStats(all, graph, dimensions)) {
53563 extent$$1 = undefined;
53567 data = context.intersects(map$$1.extent().intersection(extent$$1));
53568 var set$$1 = set(lodash.map(data, 'id'));
53569 filter = function(d) { return set$$1.has(d.id); };
53573 filter = utilFunctor(true);
53577 data = features.filter(data, graph);
53579 surface.selectAll('.data-layer-osm')
53580 .call(drawVertices, graph, data, filter, map$$1.extent(), map$$1.zoom())
53581 .call(drawLines, graph, data, filter)
53582 .call(drawAreas, graph, data, filter)
53583 .call(drawMidpoints, graph, data, filter, map$$1.trimmedExtent())
53584 .call(drawLabels, graph, data, filter, dimensions, !difference && !extent$$1)
53585 .call(drawPoints, graph, data, filter);
53587 dispatch$$1.call('drawn', this, {full: true});
53591 function editOff() {
53592 context.features().resetStats();
53593 surface.selectAll('.layer-osm *').remove();
53594 dispatch$$1.call('drawn', this, {full: true});
53598 function dblClick() {
53599 if (!dblclickEnabled) {
53600 event.preventDefault();
53601 event.stopImmediatePropagation();
53606 function zoomPan(manualEvent) {
53607 var eventTransform = (manualEvent || event).transform;
53609 if (transformStart.x === eventTransform.x &&
53610 transformStart.y === eventTransform.y &&
53611 transformStart.k === eventTransform.k) {
53612 return; // no change
53615 if (ktoz(eventTransform.k * 2 * Math.PI) < minzoom) {
53616 surface.interrupt();
53617 uiFlash(context.container())
53618 .select('.content')
53619 .text(t('cannot_zoom'));
53620 setZoom(context.minEditableZoom(), true);
53622 dispatch$$1.call('move', this, map$$1);
53626 projection.transform(eventTransform);
53628 var scale = eventTransform.k / transformStart.k,
53629 tX = (eventTransform.x / scale - transformStart.x) * scale,
53630 tY = (eventTransform.y / scale - transformStart.y) * scale;
53632 transformed = true;
53633 utilSetTransform(supersurface, tX, tY, scale);
53636 dispatch$$1.call('move', this, map$$1);
53640 function resetTransform() {
53641 if (!transformed) return false;
53643 surface.selectAll('.radial-menu').interrupt().remove();
53644 utilSetTransform(supersurface, 0, 0);
53645 transformed = false;
53650 function redraw(difference, extent$$1) {
53651 if (!surface || !redrawEnabled) return;
53653 // If we are in the middle of a zoom/pan, we can't do differenced redraws.
53654 // It would result in artifacts where differenced entities are redrawn with
53655 // one transform and unchanged entities with another.
53656 if (resetTransform()) {
53657 difference = extent$$1 = undefined;
53660 var z = String(~~map$$1.zoom());
53661 if (surface.attr('data-zoom') !== z) {
53662 surface.attr('data-zoom', z)
53663 .classed('low-zoom', z <= 16);
53667 supersurface.call(context.background());
53674 if (map$$1.editable()) {
53675 context.loadTiles(projection, dimensions);
53676 drawVector(difference, extent$$1);
53681 transformStart = projection.transform();
53687 var queueRedraw = lodash.throttle(redraw, 750);
53690 var immediateRedraw = function(difference, extent$$1) {
53691 if (!difference && !extent$$1) queueRedraw.cancel();
53692 redraw(difference, extent$$1);
53696 function pointLocation(p) {
53697 var translate = projection.translate(),
53698 scale = projection.scale() * 2 * Math.PI;
53699 return [(p[0] - translate[0]) / scale, (p[1] - translate[1]) / scale];
53703 function locationPoint(l) {
53704 var translate = projection.translate(),
53705 scale = projection.scale() * 2 * Math.PI;
53706 return [l[0] * scale + translate[0], l[1] * scale + translate[1]];
53710 map$$1.mouse = function() {
53711 var e = mousemove || event, s;
53712 while ((s = e.sourceEvent)) e = s;
53713 return mouse$$1(e);
53717 map$$1.mouseCoordinates = function() {
53718 return projection.invert(map$$1.mouse());
53722 map$$1.dblclickEnable = function(_) {
53723 if (!arguments.length) return dblclickEnabled;
53724 dblclickEnabled = _;
53729 map$$1.redrawEnable = function(_) {
53730 if (!arguments.length) return redrawEnabled;
53736 function setZoom(z2, force, duration) {
53737 if (z2 === map$$1.zoom() && !force) {
53741 var k = projection.scale(),
53742 k2 = Math.max(ztok(2), Math.min(ztok(24), ztok(z2))) / (2 * Math.PI),
53743 center = pxCenter(),
53744 l = pointLocation(center);
53746 projection.scale(k2);
53748 var t$$1 = projection.translate();
53749 l = locationPoint(l);
53751 t$$1[0] += center[0] - l[0];
53752 t$$1[1] += center[1] - l[1];
53755 projection.scale(k); // reset scale
53758 .duration(duration)
53759 .on('start', function() { map$$1.startEase(); })
53760 .call(zoom$$1.transform, identity$6.translate(t$$1[0], t$$1[1]).scale(k2));
53762 projection.translate(t$$1);
53763 transformStart = projection.transform();
53764 _selection.call(zoom$$1.transform, transformStart);
53771 function setCenter(loc2, duration) {
53772 var c = map$$1.center();
53773 if (loc2[0] === c[0] && loc2[1] === c[1]) {
53777 var t$$1 = projection.translate(),
53778 k = projection.scale(),
53780 ll = projection(loc2);
53782 t$$1[0] = t$$1[0] - ll[0] + pxC[0];
53783 t$$1[1] = t$$1[1] - ll[1] + pxC[1];
53788 .duration(duration)
53789 .on('start', function() { map$$1.startEase(); })
53790 .call(zoom$$1.transform, identity$6.translate(t$$1[0], t$$1[1]).scale(k));
53792 projection.translate(t$$1);
53793 transformStart = projection.transform();
53794 _selection.call(zoom$$1.transform, transformStart);
53801 map$$1.pan = function(delta, duration) {
53802 var t$$1 = projection.translate(),
53803 k = projection.scale();
53805 t$$1[0] += delta[0];
53806 t$$1[1] += delta[1];
53811 .duration(duration)
53812 .on('start', function() { map$$1.startEase(); })
53813 .call(zoom$$1.transform, identity$6.translate(t$$1[0], t$$1[1]).scale(k));
53815 projection.translate(t$$1);
53816 transformStart = projection.transform();
53817 _selection.call(zoom$$1.transform, transformStart);
53818 dispatch$$1.call('move', this, map$$1);
53826 map$$1.dimensions = function(_) {
53827 if (!arguments.length) return dimensions;
53828 var center = map$$1.center();
53830 drawLayers.dimensions(dimensions);
53831 context.background().dimensions(dimensions);
53832 projection.clipExtent([[0, 0], dimensions]);
53833 mouse$$1 = utilFastMouse(supersurface.node());
53841 function zoomIn(delta) {
53842 setZoom(~~map$$1.zoom() + delta, true, 250);
53845 function zoomOut(delta) {
53846 setZoom(~~map$$1.zoom() - delta, true, 250);
53849 map$$1.zoomIn = function() { zoomIn(1); };
53850 map$$1.zoomInFurther = function() { zoomIn(4); };
53852 map$$1.zoomOut = function() { zoomOut(1); };
53853 map$$1.zoomOutFurther = function() { zoomOut(4); };
53856 map$$1.center = function(loc2) {
53857 if (!arguments.length) {
53858 return projection.invert(pxCenter());
53861 if (setCenter(loc2)) {
53862 dispatch$$1.call('move', this, map$$1);
53870 map$$1.zoom = function(z2) {
53871 if (!arguments.length) {
53872 return Math.max(ktoz(projection.scale() * 2 * Math.PI), 0);
53875 if (z2 < minzoom) {
53876 surface.interrupt();
53877 uiFlash(context.container())
53878 .select('.content')
53879 .text(t('cannot_zoom'));
53880 z2 = context.minEditableZoom();
53884 dispatch$$1.call('move', this, map$$1);
53892 map$$1.zoomTo = function(entity, zoomLimits) {
53893 var extent$$1 = entity.extent(context.graph());
53894 if (!isFinite(extent$$1.area())) return;
53896 var z2 = map$$1.trimmedExtentZoom(extent$$1);
53897 zoomLimits = zoomLimits || [context.minEditableZoom(), 20];
53898 map$$1.centerZoom(extent$$1.center(), Math.min(Math.max(z2, zoomLimits[0]), zoomLimits[1]));
53902 map$$1.centerZoom = function(loc2, z2) {
53903 var centered = setCenter(loc2),
53904 zoomed = setZoom(z2);
53906 if (centered || zoomed) {
53907 dispatch$$1.call('move', this, map$$1);
53915 map$$1.centerEase = function(loc2, duration) {
53916 duration = duration || 250;
53917 setCenter(loc2, duration);
53922 map$$1.zoomEase = function(z2, duration) {
53923 duration = duration || 250;
53924 setZoom(z2, false, duration);
53929 map$$1.startEase = function() {
53930 utilBindOnce(surface, 'mousedown.ease', function() {
53931 map$$1.cancelEase();
53937 map$$1.cancelEase = function() {
53938 _selection.interrupt();
53943 map$$1.extent = function(_) {
53944 if (!arguments.length) {
53945 return new geoExtent$$1(projection.invert([0, dimensions[1]]),
53946 projection.invert([dimensions[0], 0]));
53948 var extent$$1 = geoExtent$$1(_);
53949 map$$1.centerZoom(extent$$1.center(), map$$1.extentZoom(extent$$1));
53954 map$$1.trimmedExtent = function(_) {
53955 if (!arguments.length) {
53956 var headerY = 60, footerY = 30, pad = 10;
53957 return new geoExtent$$1(projection.invert([pad, dimensions[1] - footerY - pad]),
53958 projection.invert([dimensions[0] - pad, headerY + pad]));
53960 var extent$$1 = geoExtent$$1(_);
53961 map$$1.centerZoom(extent$$1.center(), map$$1.trimmedExtentZoom(extent$$1));
53966 function calcZoom(extent$$1, dim) {
53967 var tl = projection([extent$$1[0][0], extent$$1[1][1]]),
53968 br = projection([extent$$1[1][0], extent$$1[0][1]]);
53970 // Calculate maximum zoom that fits extent
53971 var hFactor = (br[0] - tl[0]) / dim[0],
53972 vFactor = (br[1] - tl[1]) / dim[1],
53973 hZoomDiff = Math.log(Math.abs(hFactor)) / Math.LN2,
53974 vZoomDiff = Math.log(Math.abs(vFactor)) / Math.LN2,
53975 newZoom = map$$1.zoom() - Math.max(hZoomDiff, vZoomDiff);
53981 map$$1.extentZoom = function(_) {
53982 return calcZoom(geoExtent$$1(_), dimensions);
53986 map$$1.trimmedExtentZoom = function(_) {
53987 var trimY = 120, trimX = 40,
53988 trimmed = [dimensions[0] - trimX, dimensions[1] - trimY];
53989 return calcZoom(geoExtent$$1(_), trimmed);
53993 map$$1.editable = function() {
53994 return map$$1.zoom() >= context.minEditableZoom();
53998 map$$1.minzoom = function(_) {
53999 if (!arguments.length) return minzoom;
54005 map$$1.layers = drawLayers;
54008 return utilRebind(map$$1, dispatch$$1, 'on');
54011 var TAU = 2 * Math.PI;
54012 function ztok(z) { return 256 * Math.pow(2, z) / TAU; }
54013 function ktoz(k) { return Math.log(k * TAU) / Math.LN2 - 8; }
54014 function vecSub(a, b) { return [ a[0] - b[0], a[1] - b[1] ]; }
54015 function vecScale(a, b) { return [ a[0] * b, a[1] * b ]; }
54018 function uiMapInMap(context) {
54022 function map_in_map(selection$$1) {
54023 var backgroundLayer = rendererTileLayer(context),
54024 overlayLayers = {},
54025 projection = geoRawMercator(),
54026 gpxLayer = svgGpx(projection, context).showLabels(false),
54027 debugLayer = svgDebug(projection, context),
54029 .scaleExtent([ztok(0.5), ztok(24)])
54030 .on('start', zoomStarted)
54031 .on('zoom', zoomed)
54032 .on('end', zoomEnded),
54033 isTransformed = false,
54035 skipEvents = false,
54037 zDiff = 6, // by default, minimap renders at (main zoom - 6)
54038 wrap = select(null),
54039 tiles = select(null),
54040 viewport = select(null),
54041 tStart, // transform at start of gesture
54042 tCurr, // transform at most recent event
54046 function zoomStarted() {
54047 if (skipEvents) return;
54048 tStart = tCurr = projection.transform();
54053 function zoomed() {
54054 if (skipEvents) return;
54056 var x = event.transform.x,
54057 y = event.transform.y,
54058 k = event.transform.k,
54059 isZooming = (k !== tStart.k),
54060 isPanning = (x !== tStart.x || y !== tStart.y);
54062 if (!isZooming && !isPanning) {
54063 return; // no change
54066 // lock in either zooming or panning, don't allow both in minimap.
54068 gesture = isZooming ? 'zoom' : 'pan';
54071 var tMini = projection.transform(),
54074 if (gesture === 'zoom') {
54075 var dMini = utilGetDimensions(wrap),
54076 cMini = vecScale(dMini, 0.5);
54077 scale = k / tMini.k;
54078 tX = (cMini[0] / scale - cMini[0]) * scale;
54079 tY = (cMini[1] / scale - cMini[1]) * scale;
54087 utilSetTransform(tiles, tX, tY, scale);
54088 utilSetTransform(viewport, 0, 0, scale);
54089 isTransformed = true;
54090 tCurr = identity$6.translate(x, y).scale(k);
54092 var zMain = ktoz(context.projection.scale()),
54095 zDiff = zMain - zMini;
54101 function zoomEnded() {
54102 if (skipEvents) return;
54103 if (gesture !== 'pan') return;
54105 updateProjection();
54107 var dMini = utilGetDimensions(wrap),
54108 cMini = vecScale(dMini, 0.5);
54109 context.map().center(projection.invert(cMini)); // recenter main map..
54113 function updateProjection() {
54114 var loc = context.map().center(),
54115 dMini = utilGetDimensions(wrap),
54116 cMini = vecScale(dMini, 0.5),
54117 tMain = context.projection.transform(),
54118 zMain = ktoz(tMain.k),
54119 zMini = Math.max(zMain - zDiff, 0.5),
54120 kMini = ztok(zMini);
54123 .translate([tMain.x, tMain.y])
54126 var point = projection(loc),
54127 mouse$$1 = (gesture === 'pan') ? vecSub([tCurr.x, tCurr.y], [tStart.x, tStart.y]) : [0, 0],
54128 xMini = cMini[0] - point[0] + tMain.x + mouse$$1[0],
54129 yMini = cMini[1] - point[1] + tMain.y + mouse$$1[1];
54132 .translate([xMini, yMini])
54133 .clipExtent([[0, 0], dMini]);
54135 tCurr = projection.transform();
54137 if (isTransformed) {
54138 utilSetTransform(tiles, 0, 0);
54139 utilSetTransform(viewport, 0, 0);
54140 isTransformed = false;
54144 .scaleExtent([ztok(0.5), ztok(zMain - 3)]);
54147 wrap.call(zoom$$1.transform, tCurr);
54148 skipEvents = false;
54152 function redraw() {
54153 clearTimeout(timeoutId);
54154 if (isHidden) return;
54156 updateProjection();
54158 var dMini = utilGetDimensions(wrap),
54159 zMini = ktoz(projection.scale());
54161 // setup tile container
54163 .selectAll('.map-in-map-tiles')
54166 tiles = tiles.enter()
54168 .attr('class', 'map-in-map-tiles')
54171 // redraw background
54173 .source(context.background().baseLayerSource())
54174 .projection(projection)
54175 .dimensions(dMini);
54177 var background = tiles
54178 .selectAll('.map-in-map-background')
54183 .attr('class', 'map-in-map-background')
54185 .call(backgroundLayer);
54189 var overlaySources = context.background().overlayLayerSources();
54190 var activeOverlayLayers = [];
54191 for (var i = 0; i < overlaySources.length; i++) {
54192 if (overlaySources[i].validZoom(zMini)) {
54193 if (!overlayLayers[i]) overlayLayers[i] = rendererTileLayer(context);
54194 activeOverlayLayers.push(overlayLayers[i]
54195 .source(overlaySources[i])
54196 .projection(projection)
54197 .dimensions(dMini));
54201 var overlay = tiles
54202 .selectAll('.map-in-map-overlay')
54205 overlay = overlay.enter()
54207 .attr('class', 'map-in-map-overlay')
54211 var overlays = overlay
54213 .data(activeOverlayLayers, function(d) { return d.source().name(); });
54218 overlays = overlays.enter()
54221 .each(function(layer) { select(this).call(layer); });
54224 var dataLayers = tiles
54225 .selectAll('.map-in-map-data')
54231 dataLayers = dataLayers.enter()
54233 .attr('class', 'map-in-map-data')
54239 // redraw viewport bounding box
54240 if (gesture !== 'pan') {
54241 var getPath = index$5(projection),
54242 bbox = { type: 'Polygon', coordinates: [context.map().extent().polygon()] };
54244 viewport = wrap.selectAll('.map-in-map-viewport')
54247 viewport = viewport.enter()
54249 .attr('class', 'map-in-map-viewport')
54253 var path$$1 = viewport.selectAll('.map-in-map-bbox')
54258 .attr('class', 'map-in-map-bbox')
54260 .attr('d', getPath)
54261 .classed('thick', function(d) { return getPath.area(d) < 30; });
54266 function queueRedraw() {
54267 clearTimeout(timeoutId);
54268 timeoutId = setTimeout(function() { redraw(); }, 750);
54272 function toggle() {
54273 if (event) event.preventDefault();
54275 isHidden = !isHidden;
54277 var label = select('.minimap-toggle');
54278 label.classed('active', !isHidden)
54279 .select('input').property('checked', !isHidden);
54283 .style('display', 'block')
54284 .style('opacity', '1')
54287 .style('opacity', '0')
54288 .on('end', function() {
54289 selection$$1.selectAll('.map-in-map')
54290 .style('display', 'none');
54294 .style('display', 'block')
54295 .style('opacity', '0')
54298 .style('opacity', '1')
54299 .on('end', function() {
54306 uiMapInMap.toggle = toggle;
54308 wrap = selection$$1.selectAll('.map-in-map')
54311 wrap = wrap.enter()
54313 .attr('class', 'map-in-map')
54314 .style('display', (isHidden ? 'none' : 'block'))
54316 .on('dblclick.zoom', null)
54320 .on('drawn.map-in-map', function(drawn) {
54321 if (drawn.full === true) {
54328 var keybinding = d3keybinding('map-in-map')
54338 function uiTooltipHtml(text, key) {
54339 var s = '<span>' + text + '</span>';
54341 s += '<div class="keyhint-wrap">' +
54342 '<span> ' + (t('tooltip_keyhint')) + ' </span>' +
54343 '<span class="keyhint"> ' + key + '</span></div>';
54348 function uiBackground(context) {
54350 detected = utilDetect(),
54351 opacities = [1, 0.75, 0.5, 0.25],
54353 ['right', [0.5, 0]],
54354 ['top', [0, -0.5]],
54355 ['left', [-0.5, 0]],
54356 ['bottom', [0, 0.5]]],
54357 opacityDefault = (context.storage('background-opacity') !== null) ?
54358 (+context.storage('background-opacity')) : 1.0,
54359 customTemplate = context.storage('background-custom-template') || '',
54362 // Can be 0 from <1.3.0 use or due to issue #1923.
54363 if (opacityDefault === 0) opacityDefault = 1.0;
54366 function background(selection$$1) {
54368 function sortSources(a, b) {
54369 return a.best() && !b.best() ? -1
54370 : b.best() && !a.best() ? 1
54371 : descending(a.area(), b.area()) || ascending(a.name(), b.name()) || 0;
54375 function setOpacity(d) {
54376 var bg = context.container().selectAll('.layer-background')
54378 .style('opacity', d)
54379 .attr('data-opacity', d);
54381 if (!detected.opera) {
54382 utilSetTransform(bg, 0, 0);
54385 opacityList.selectAll('li')
54386 .classed('active', function(_) { return _ === d; });
54388 context.storage('background-opacity', d);
54392 function setTooltips(selection$$1) {
54393 selection$$1.each(function(d, i, nodes) {
54394 var item = select(this).select('label'),
54395 placement = (i < nodes.length / 2) ? 'bottom' : 'top';
54397 if (d === previous) {
54398 item.call(tooltip()
54399 .placement(placement)
54401 .title(function() {
54402 var tip = '<div>' + t('background.switch') + '</div>';
54403 return uiTooltipHtml(tip, uiCmd('⌘B'));
54406 } else if (d.description) {
54407 item.call(tooltip()
54408 .placement(placement)
54409 .title(d.description)
54412 item.call(tooltip().destroy);
54418 function selectLayer() {
54419 function active$$1(d) {
54420 return context.background().showsLayer(d);
54423 content.selectAll('.layer, .custom_layer')
54424 .classed('active', active$$1)
54425 .classed('switch', function(d) { return d === previous; })
54427 .selectAll('input')
54428 .property('checked', active$$1);
54432 function clickSetSource(d) {
54433 event.preventDefault();
54434 previous = context.background().baseLayerSource();
54435 context.background().baseLayerSource(d);
54437 document.activeElement.blur();
54441 function editCustom() {
54442 event.preventDefault();
54443 var template = window.prompt(t('background.custom_prompt'), customTemplate);
54445 template.indexOf('google.com') !== -1 ||
54446 template.indexOf('googleapis.com') !== -1 ||
54447 template.indexOf('google.ru') !== -1) {
54451 setCustom(template);
54455 function setCustom(template) {
54456 context.storage('background-custom-template', template);
54457 var d = rendererBackgroundSource.Custom(template);
54458 content.selectAll('.custom_layer').datum(d);
54463 function clickSetOverlay(d) {
54464 event.preventDefault();
54465 context.background().toggleOverlayLayer(d);
54467 document.activeElement.blur();
54471 function drawList(layerList, type, change, filter) {
54472 var sources = context.background()
54473 .sources(context.map().extent())
54476 var layerLinks = layerList.selectAll('li.layer')
54477 .data(sources, function(d) { return d.name(); });
54482 var enter = layerLinks.enter()
54483 .insert('li', '.custom_layer')
54484 .attr('class', 'layer')
54485 .classed('best', function(d) { return d.best(); });
54487 enter.filter(function(d) { return d.best(); })
54489 .attr('class', 'best')
54491 .title(t('background.best_imagery'))
54492 .placement((textDirection === 'rtl') ? 'right' : 'left'))
54501 .attr('type', type)
54502 .attr('name', 'layers')
54503 .on('change', change);
54507 .text(function(d) { return d.name(); });
54510 layerList.selectAll('li.layer')
54512 .style('display', layerList.selectAll('li.layer').data().length > 0 ? 'block' : 'none');
54516 function update() {
54517 backgroundList.call(drawList, 'radio', clickSetSource, function(d) { return !d.overlay; });
54518 overlayList.call(drawList, 'checkbox', clickSetOverlay, function(d) { return d.overlay; });
54522 var source = context.background().baseLayerSource();
54523 if (source.id === 'custom') {
54524 customTemplate = source.template;
54531 function updateOffsetVal() {
54532 var meters = geoOffsetToMeters(context.background().offset()),
54533 x = +meters[0].toFixed(2),
54534 y = +meters[1].toFixed(2);
54536 selectAll('.nudge-inner-rect')
54538 .classed('error', false)
54539 .property('value', x + ', ' + y);
54541 selectAll('.nudge-reset')
54542 .classed('disabled', function() {
54543 return (x === 0 && y === 0);
54548 function resetOffset() {
54549 if (event.button !== 0) return;
54550 context.background().offset([0, 0]);
54555 function nudge(d) {
54556 context.background().nudge(d, context.map().zoom());
54561 function buttonOffset(d) {
54562 if (event.button !== 0) return;
54563 var timeout$$1 = window.setTimeout(function() {
54564 interval$$1 = window.setInterval(nudge.bind(null, d), 100);
54568 function doneNudge() {
54569 window.clearTimeout(timeout$$1);
54570 window.clearInterval(interval$$1);
54572 .on('mouseup.buttonoffset', null, true)
54573 .on('mousedown.buttonoffset', null, true);
54577 .on('mouseup.buttonoffset', doneNudge, true)
54578 .on('mousedown.buttonoffset', doneNudge, true);
54584 function inputOffset() {
54585 if (event.button !== 0) return;
54586 var input = select(this);
54587 var d = input.node().value;
54589 if (d === '') return resetOffset();
54591 d = d.replace(/;/g, ',').split(',').map(function(n) {
54592 // if n is NaN, it will always get mapped to false.
54593 return !isNaN(n) && n;
54596 if (d.length !== 2 || !d[0] || !d[1]) {
54597 input.classed('error', true);
54601 context.background().offset(geoMetersToOffset(d));
54606 function dragOffset() {
54607 if (event.button !== 0) return;
54608 var origin = [event.clientX, event.clientY];
54610 context.container()
54612 .attr('class', 'nudge-surface');
54615 .on('mousemove.offset', function() {
54616 var latest = [event.clientX, event.clientY];
54618 -(origin[0] - latest[0]) / 4,
54619 -(origin[1] - latest[1]) / 4
54625 .on('mouseup.offset', function() {
54626 if (event.button !== 0) return;
54627 selectAll('.nudge-surface')
54631 .on('mousemove.offset', null)
54632 .on('mouseup.offset', null);
54635 event.preventDefault();
54644 function toggle() {
54645 if (event) event.preventDefault();
54646 tooltipBehavior.hide(button);
54647 setVisible(!button.classed('active'));
54651 function quickSwitch() {
54653 clickSetSource(previous);
54658 function setVisible(show) {
54659 if (show !== shown) {
54660 button.classed('active', show);
54664 selection$$1.on('mousedown.background-inside', function() {
54665 event.stopPropagation();
54668 .style('display', 'block')
54669 .style('right', '-300px')
54672 .style('right', '0px');
54675 .style('display', 'block')
54676 .style('right', '0px')
54679 .style('right', '-300px')
54680 .on('end', function() {
54681 select(this).style('display', 'none');
54683 selection$$1.on('mousedown.background-inside', null);
54689 var content = selection$$1
54691 .attr('class', 'fillL map-overlay col3 content hide'),
54692 tooltipBehavior = tooltip()
54693 .placement((textDirection === 'rtl') ? 'right' : 'left')
54695 .title(uiTooltipHtml(t('background.description'), key)),
54696 button = selection$$1
54698 .attr('tabindex', -1)
54699 .on('click', toggle)
54700 .call(svgIcon('#icon-layers', 'light'))
54701 .call(tooltipBehavior),
54705 /* opacity switcher */
54707 var opawrap = content
54709 .attr('class', 'opacity-options-wrapper');
54713 .text(t('background.title'));
54715 var opacityList = opawrap
54717 .attr('class', 'opacity-options');
54719 opacityList.selectAll('div.opacity')
54723 .attr('data-original-title', function(d) {
54724 return t('background.percent_brightness', { opacity: (d * 100) });
54726 .on('click.set-opacity', setOpacity)
54727 .html('<div class="select-box"></div>')
54729 .placement((textDirection === 'rtl') ? 'right' : 'left'))
54731 .attr('class', 'opacity')
54732 .style('opacity', function(d) { return 1.25 - d; });
54735 /* background switcher */
54737 var backgroundList = content
54739 .attr('class', 'layer-list')
54740 .attr('dir', 'auto');
54742 var custom = backgroundList
54744 .attr('class', 'custom_layer')
54745 .datum(rendererBackgroundSource.Custom());
54749 .attr('class', 'layer-browse')
54751 .title(t('background.custom_button'))
54752 .placement((textDirection === 'rtl') ? 'right' : 'left'))
54753 .on('click', editCustom)
54754 .call(svgIcon('#icon-search'));
54761 .attr('type', 'radio')
54762 .attr('name', 'layers')
54763 .on('change', function () {
54764 if (customTemplate) {
54765 setCustom(customTemplate);
54773 .text(t('background.custom'));
54777 .attr('class', 'imagery-faq')
54779 .attr('target', '_blank')
54780 .attr('tabindex', -1)
54781 .call(svgIcon('#icon-out-link', 'inline'))
54782 .attr('href', 'https://github.com/openstreetmap/iD/blob/master/FAQ.md#how-can-i-report-an-issue-with-background-imagery')
54784 .text(t('background.imagery_source_faq'));
54786 var overlayList = content
54788 .attr('class', 'layer-list');
54790 var controls = content
54792 .attr('class', 'controls-list');
54795 /* minimap toggle */
54797 var minimapLabel = controls
54801 .title(uiTooltipHtml(t('background.minimap.tooltip'), '/'))
54806 .classed('minimap-toggle', true)
54808 .attr('type', 'checkbox')
54809 .on('change', function() {
54810 uiMapInMap.toggle();
54811 event.preventDefault();
54816 .text(t('background.minimap.description'));
54819 /* imagery offset controls */
54821 var adjustments = content
54823 .attr('class', 'adjustments');
54827 .text(t('background.fix_misalignment'))
54829 .classed('hide-toggle', true)
54830 .classed('expanded', false)
54831 .on('click', function() {
54832 if (event.button !== 0) return;
54833 var exp = select(this).classed('expanded');
54834 nudgeContainer.style('display', exp ? 'none' : 'block');
54835 select(this).classed('expanded', !exp);
54836 event.preventDefault();
54839 var nudgeContainer = adjustments
54841 .attr('class', 'nudge-container cf')
54842 .style('display', 'none');
54846 .attr('class', 'nudge-instructions')
54847 .text(t('background.offset'));
54849 var nudgeRect = nudgeContainer
54851 .attr('class', 'nudge-outer-rect')
54852 .on('mousedown', dragOffset);
54856 .attr('class', 'nudge-inner-rect')
54858 .on('change', inputOffset)
54859 .on('mousedown', function() {
54860 if (event.button !== 0) return;
54861 event.stopPropagation();
54866 .selectAll('button')
54867 .data(directions).enter()
54869 .attr('class', function(d) { return d[0] + ' nudge'; })
54870 .on('mousedown', function(d) {
54871 if (event.button !== 0) return;
54872 buttonOffset(d[1]);
54877 .attr('title', t('background.reset'))
54878 .attr('class', 'nudge-reset disabled')
54879 .on('click', resetOffset)
54881 (textDirection === 'rtl') ? svgIcon('#icon-redo') : svgIcon('#icon-undo')
54885 .on('move.background-update', lodash.debounce(update, 1000));
54887 context.background()
54888 .on('change.background-update', update);
54892 setOpacity(opacityDefault);
54894 var keybinding = d3keybinding('background')
54896 .on(uiCmd('⌘B'), quickSwitch)
54903 context.surface().on('mousedown.background-outside', hide);
54904 context.container().on('mousedown.background-outside', hide);
54910 function uiContributors(context) {
54911 var debouncedUpdate = lodash.debounce(function() { update(); }, 1000),
54914 wrap = select(null);
54917 function update() {
54919 entities = context.intersects(context.map().extent());
54921 entities.forEach(function(entity) {
54922 if (entity && entity.user) users[entity.user] = true;
54925 var u = Object.keys(users),
54926 subset = u.slice(0, u.length > limit ? limit - 1 : limit);
54929 .call(svgIcon('#icon-nearby', 'pre-text light'));
54931 var userList = select(document.createElement('span'));
54933 userList.selectAll()
54937 .attr('class', 'user-link')
54938 .attr('href', function(d) { return context.connection().userURL(d); })
54939 .attr('target', '_blank')
54940 .attr('tabindex', -1)
54943 if (u.length > limit) {
54944 var count = select(document.createElement('span'));
54947 .attr('target', '_blank')
54948 .attr('tabindex', -1)
54949 .attr('href', function() {
54950 return context.connection().changesetsURL(context.map().center(), context.map().zoom());
54952 .text(u.length - limit + 1);
54954 wrap.append('span')
54955 .html(t('contributors.truncated_list', { users: userList.html(), count: count.html() }));
54958 wrap.append('span')
54959 .html(t('contributors.list', { users: userList.html() }));
54966 .style('opacity', 0);
54968 } else if (hidden) {
54971 .style('opacity', 1);
54976 return function(selection$$1) {
54977 wrap = selection$$1;
54980 context.connection().on('loaded.contributors', debouncedUpdate);
54981 context.map().on('move.contributors', debouncedUpdate);
54985 function uiFeatureInfo(context) {
54986 function update(selection$$1) {
54987 var features = context.features(),
54988 stats = features.stats(),
54990 hiddenList = lodash.compact(lodash.map(features.hidden(), function(k) {
54993 return String(stats[k]) + ' ' + t('feature.' + k + '.description');
54997 selection$$1.html('');
54999 if (hiddenList.length) {
55000 var tooltipBehavior = tooltip()
55003 .title(function() {
55004 return uiTooltipHtml(hiddenList.join('<br/>'));
55007 var warning = selection$$1.append('a')
55009 .attr('tabindex', -1)
55010 .html(t('feature_info.hidden_warning', { count: count }))
55011 .call(tooltipBehavior)
55012 .on('click', function() {
55013 tooltipBehavior.hide(warning);
55014 // open map data panel?
55015 event.preventDefault();
55020 .classed('hide', !hiddenList.length);
55024 return function(selection$$1) {
55025 update(selection$$1);
55027 context.features().on('change.feature_info', function() {
55028 update(selection$$1);
55033 function uiFullScreen(context) {
55034 var element = context.container().node(),
55035 keybinding = d3keybinding('full-screen');
55039 function getFullScreenFn() {
55040 if (element.requestFullscreen) {
55041 return element.requestFullscreen;
55042 } else if (element.msRequestFullscreen) {
55043 return element.msRequestFullscreen;
55044 } else if (element.mozRequestFullScreen) {
55045 return element.mozRequestFullScreen;
55046 } else if (element.webkitRequestFullscreen) {
55047 return element.webkitRequestFullscreen;
55052 function getExitFullScreenFn() {
55053 if (document.exitFullscreen) {
55054 return document.exitFullscreen;
55055 } else if (document.msExitFullscreen) {
55056 return document.msExitFullscreen;
55057 } else if (document.mozCancelFullScreen) {
55058 return document.mozCancelFullScreen;
55059 } else if (document.webkitExitFullscreen) {
55060 return document.webkitExitFullscreen;
55065 function isFullScreen() {
55066 return document.fullscreenElement ||
55067 document.mozFullScreenElement ||
55068 document.webkitFullscreenElement ||
55069 document.msFullscreenElement;
55073 function isSupported() {
55074 return !!getFullScreenFn();
55078 function fullScreen() {
55079 event.preventDefault();
55080 if (!isFullScreen()) {
55081 // button.classed('active', true);
55082 getFullScreenFn().apply(element);
55084 // button.classed('active', false);
55085 getExitFullScreenFn().apply(document);
55090 return function() { // selection) {
55091 if (!isSupported())
55094 // button = selection.append('button')
55095 // .attr('title', t('full_screen'))
55096 // .attr('tabindex', -1)
55097 // .on('click', fullScreen)
55100 // button.append('span')
55101 // .attr('class', 'icon full-screen');
55104 .on('f11', fullScreen)
55105 .on(uiCmd('⌘⇧F'), fullScreen);
55112 function uiModal(selection$$1, blocking) {
55113 var keybinding = d3keybinding('modal');
55114 var previous = selection$$1.select('div.modal');
55115 var animate = previous.empty();
55117 previous.transition()
55119 .style('opacity', 0)
55122 var shaded = selection$$1
55124 .attr('class', 'shaded')
55125 .style('opacity', 0);
55127 shaded.close = function() {
55131 .style('opacity',0)
55137 .style('top','0px');
55145 .attr('class', 'modal fillL col6');
55148 shaded.on('click.remove-modal', function() {
55149 if (event.target === this) {
55154 modal.append('button')
55155 .attr('class', 'close')
55156 .on('click', shaded.close)
55157 .call(svgIcon('#icon-close'));
55160 .on('⌫', shaded.close)
55161 .on('⎋', shaded.close);
55169 .attr('class', 'content');
55172 shaded.transition().style('opacity', 1);
55174 shaded.style('opacity', 1);
55181 function uiLoading(context) {
55187 var loading = function(selection) {
55188 modalSelection = uiModal(selection, blocking);
55190 var loadertext = modalSelection.select('.content')
55191 .classed('loading-modal', true)
55193 .attr('class', 'modal-section fillL');
55197 .attr('class', 'loader')
55198 .attr('src', context.imagePath('loader-white.gif'));
55204 modalSelection.select('button.close')
55205 .attr('class', 'hide');
55211 loading.message = function(_) {
55212 if (!arguments.length) return message;
55218 loading.blocking = function(_) {
55219 if (!arguments.length) return blocking;
55225 loading.close = function() {
55226 modalSelection.remove();
55233 function uiGeolocate(context) {
55234 var geoOptions = { enableHighAccuracy: false, timeout: 6000 /* 6sec */ },
55235 locating = uiLoading(context).message(t('geolocate.locating')).blocking(true),
55240 context.enter(modeBrowse$$1(context));
55241 context.container().call(locating);
55242 navigator.geolocation.getCurrentPosition(success, error, geoOptions);
55244 // This timeout ensures that we still call finish() even if
55245 // the user declines to share their location in Firefox
55246 timeoutId = setTimeout(finish, 10000 /* 10sec */ );
55250 function success(position) {
55251 var map = context.map(),
55252 extent = geoExtent$$1([position.coords.longitude, position.coords.latitude])
55253 .padByMeters(position.coords.accuracy);
55255 map.centerZoom(extent.center(), Math.min(20, map.extentZoom(extent)));
55265 function finish() {
55266 locating.close(); // unblock ui
55267 if (timeoutId) { clearTimeout(timeoutId); }
55268 timeoutId = undefined;
55272 return function(selection) {
55273 if (!navigator.geolocation) return;
55277 .attr('tabindex', -1)
55278 .attr('title', t('geolocate.title'))
55279 .on('click', click)
55280 .call(svgIcon('#icon-geolocate', 'light'))
55282 .placement((textDirection === 'rtl') ? 'right' : 'left'));
55286 var marked = createCommonjsModule(function (module, exports) {
55288 * marked - a markdown parser
55289 * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
55290 * https://github.com/chjj/marked
55296 * Block-Level Grammar
55301 code: /^( {4}[^\n]+\n*)+/,
55303 hr: /^( *[-*_]){3,} *(?:\n+|$)/,
55304 heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
55306 lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
55307 blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
55308 list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
55309 html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
55310 def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
55312 paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
55316 block.bullet = /(?:[*+-]|\d+\.)/;
55317 block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
55318 block.item = replace(block.item, 'gm')
55319 (/bull/g, block.bullet)
55322 block.list = replace(block.list)
55323 (/bull/g, block.bullet)
55324 ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
55325 ('def', '\\n+(?=' + block.def.source + ')')
55328 block.blockquote = replace(block.blockquote)
55332 block._tag = '(?!(?:'
55333 + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
55334 + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
55335 + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';
55337 block.html = replace(block.html)
55338 ('comment', /<!--[\s\S]*?-->/)
55339 ('closed', /<(tag)[\s\S]+?<\/\1>/)
55340 ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
55341 (/tag/g, block._tag)
55344 block.paragraph = replace(block.paragraph)
55346 ('heading', block.heading)
55347 ('lheading', block.lheading)
55348 ('blockquote', block.blockquote)
55349 ('tag', '<' + block._tag)
55354 * Normal Block Grammar
55357 block.normal = merge({}, block);
55360 * GFM Block Grammar
55363 block.gfm = merge({}, block.normal, {
55364 fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,
55366 heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/
55369 block.gfm.paragraph = replace(block.paragraph)
55371 + block.gfm.fences.source.replace('\\1', '\\2') + '|'
55372 + block.list.source.replace('\\1', '\\3') + '|')
55376 * GFM + Tables Block Grammar
55379 block.tables = merge({}, block.gfm, {
55380 nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
55381 table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
55388 function Lexer(options) {
55390 this.tokens.links = {};
55391 this.options = options || marked.defaults;
55392 this.rules = block.normal;
55394 if (this.options.gfm) {
55395 if (this.options.tables) {
55396 this.rules = block.tables;
55398 this.rules = block.gfm;
55404 * Expose Block Rules
55407 Lexer.rules = block;
55410 * Static Lex Method
55413 Lexer.lex = function(src, options) {
55414 var lexer = new Lexer(options);
55415 return lexer.lex(src);
55422 Lexer.prototype.lex = function(src) {
55424 .replace(/\r\n|\r/g, '\n')
55425 .replace(/\t/g, ' ')
55426 .replace(/\u00a0/g, ' ')
55427 .replace(/\u2424/g, '\n');
55429 return this.token(src, true);
55436 Lexer.prototype.token = function(src, top, bq) {
55437 var src = src.replace(/^ +$/gm, '')
55450 if (cap = this.rules.newline.exec(src)) {
55451 src = src.substring(cap[0].length);
55452 if (cap[0].length > 1) {
55460 if (cap = this.rules.code.exec(src)) {
55461 src = src.substring(cap[0].length);
55462 cap = cap[0].replace(/^ {4}/gm, '');
55465 text: !this.options.pedantic
55466 ? cap.replace(/\n+$/, '')
55473 if (cap = this.rules.fences.exec(src)) {
55474 src = src.substring(cap[0].length);
55484 if (cap = this.rules.heading.exec(src)) {
55485 src = src.substring(cap[0].length);
55488 depth: cap[1].length,
55494 // table no leading pipe (gfm)
55495 if (top && (cap = this.rules.nptable.exec(src))) {
55496 src = src.substring(cap[0].length);
55500 header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
55501 align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
55502 cells: cap[3].replace(/\n$/, '').split('\n')
55505 for (i = 0; i < item.align.length; i++) {
55506 if (/^ *-+: *$/.test(item.align[i])) {
55507 item.align[i] = 'right';
55508 } else if (/^ *:-+: *$/.test(item.align[i])) {
55509 item.align[i] = 'center';
55510 } else if (/^ *:-+ *$/.test(item.align[i])) {
55511 item.align[i] = 'left';
55513 item.align[i] = null;
55517 for (i = 0; i < item.cells.length; i++) {
55518 item.cells[i] = item.cells[i].split(/ *\| */);
55521 this.tokens.push(item);
55527 if (cap = this.rules.lheading.exec(src)) {
55528 src = src.substring(cap[0].length);
55531 depth: cap[2] === '=' ? 1 : 2,
55538 if (cap = this.rules.hr.exec(src)) {
55539 src = src.substring(cap[0].length);
55547 if (cap = this.rules.blockquote.exec(src)) {
55548 src = src.substring(cap[0].length);
55551 type: 'blockquote_start'
55554 cap = cap[0].replace(/^ *> ?/gm, '');
55556 // Pass `top` to keep the current
55557 // "toplevel" state. This is exactly
55558 // how markdown.pl works.
55559 this.token(cap, top, true);
55562 type: 'blockquote_end'
55569 if (cap = this.rules.list.exec(src)) {
55570 src = src.substring(cap[0].length);
55574 type: 'list_start',
55575 ordered: bull.length > 1
55578 // Get each top-level item.
55579 cap = cap[0].match(this.rules.item);
55585 for (; i < l; i++) {
55588 // Remove the list item's bullet
55589 // so it is seen as the next token.
55590 space = item.length;
55591 item = item.replace(/^ *([*+-]|\d+\.) +/, '');
55593 // Outdent whatever the
55594 // list item contains. Hacky.
55595 if (~item.indexOf('\n ')) {
55596 space -= item.length;
55597 item = !this.options.pedantic
55598 ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
55599 : item.replace(/^ {1,4}/gm, '');
55602 // Determine whether the next list item belongs here.
55603 // Backpedal if it does not belong in this list.
55604 if (this.options.smartLists && i !== l - 1) {
55605 b = block.bullet.exec(cap[i + 1])[0];
55606 if (bull !== b && !(bull.length > 1 && b.length > 1)) {
55607 src = cap.slice(i + 1).join('\n') + src;
55612 // Determine whether item is loose or not.
55613 // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
55614 // for discount behavior.
55615 loose = next || /\n\n(?!\s*$)/.test(item);
55617 next = item.charAt(item.length - 1) === '\n';
55618 if (!loose) loose = next;
55623 ? 'loose_item_start'
55624 : 'list_item_start'
55628 this.token(item, false, bq);
55631 type: 'list_item_end'
55643 if (cap = this.rules.html.exec(src)) {
55644 src = src.substring(cap[0].length);
55646 type: this.options.sanitize
55649 pre: !this.options.sanitizer
55650 && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
55657 if ((!bq && top) && (cap = this.rules.def.exec(src))) {
55658 src = src.substring(cap[0].length);
55659 this.tokens.links[cap[1].toLowerCase()] = {
55667 if (top && (cap = this.rules.table.exec(src))) {
55668 src = src.substring(cap[0].length);
55672 header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
55673 align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
55674 cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
55677 for (i = 0; i < item.align.length; i++) {
55678 if (/^ *-+: *$/.test(item.align[i])) {
55679 item.align[i] = 'right';
55680 } else if (/^ *:-+: *$/.test(item.align[i])) {
55681 item.align[i] = 'center';
55682 } else if (/^ *:-+ *$/.test(item.align[i])) {
55683 item.align[i] = 'left';
55685 item.align[i] = null;
55689 for (i = 0; i < item.cells.length; i++) {
55690 item.cells[i] = item.cells[i]
55691 .replace(/^ *\| *| *\| *$/g, '')
55695 this.tokens.push(item);
55700 // top-level paragraph
55701 if (top && (cap = this.rules.paragraph.exec(src))) {
55702 src = src.substring(cap[0].length);
55705 text: cap[1].charAt(cap[1].length - 1) === '\n'
55706 ? cap[1].slice(0, -1)
55713 if (cap = this.rules.text.exec(src)) {
55714 // Top-level should never reach here.
55715 src = src.substring(cap[0].length);
55725 Error('Infinite loop on byte: ' + src.charCodeAt(0));
55729 return this.tokens;
55733 * Inline-Level Grammar
55737 escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
55738 autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
55740 tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
55741 link: /^!?\[(inside)\]\(href\)/,
55742 reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
55743 nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
55744 strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
55745 em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
55746 code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
55747 br: /^ {2,}\n(?!\s*$)/,
55749 text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
55752 inline._inside = /(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;
55753 inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
55755 inline.link = replace(inline.link)
55756 ('inside', inline._inside)
55757 ('href', inline._href)
55760 inline.reflink = replace(inline.reflink)
55761 ('inside', inline._inside)
55765 * Normal Inline Grammar
55768 inline.normal = merge({}, inline);
55771 * Pedantic Inline Grammar
55774 inline.pedantic = merge({}, inline.normal, {
55775 strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
55776 em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
55780 * GFM Inline Grammar
55783 inline.gfm = merge({}, inline.normal, {
55784 escape: replace(inline.escape)('])', '~|])')(),
55785 url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
55786 del: /^~~(?=\S)([\s\S]*?\S)~~/,
55787 text: replace(inline.text)
55789 ('|', '|https?://|')
55794 * GFM + Line Breaks Inline Grammar
55797 inline.breaks = merge({}, inline.gfm, {
55798 br: replace(inline.br)('{2,}', '*')(),
55799 text: replace(inline.gfm.text)('{2,}', '*')()
55803 * Inline Lexer & Compiler
55806 function InlineLexer(links, options) {
55807 this.options = options || marked.defaults;
55808 this.links = links;
55809 this.rules = inline.normal;
55810 this.renderer = this.options.renderer || new Renderer;
55811 this.renderer.options = this.options;
55815 Error('Tokens array requires a `links` property.');
55818 if (this.options.gfm) {
55819 if (this.options.breaks) {
55820 this.rules = inline.breaks;
55822 this.rules = inline.gfm;
55824 } else if (this.options.pedantic) {
55825 this.rules = inline.pedantic;
55830 * Expose Inline Rules
55833 InlineLexer.rules = inline;
55836 * Static Lexing/Compiling Method
55839 InlineLexer.output = function(src, links, options) {
55840 var inline = new InlineLexer(links, options);
55841 return inline.output(src);
55848 InlineLexer.prototype.output = function(src) {
55857 if (cap = this.rules.escape.exec(src)) {
55858 src = src.substring(cap[0].length);
55864 if (cap = this.rules.autolink.exec(src)) {
55865 src = src.substring(cap[0].length);
55866 if (cap[2] === '@') {
55867 text = cap[1].charAt(6) === ':'
55868 ? this.mangle(cap[1].substring(7))
55869 : this.mangle(cap[1]);
55870 href = this.mangle('mailto:') + text;
55872 text = escape(cap[1]);
55875 out += this.renderer.link(href, null, text);
55880 if (!this.inLink && (cap = this.rules.url.exec(src))) {
55881 src = src.substring(cap[0].length);
55882 text = escape(cap[1]);
55884 out += this.renderer.link(href, null, text);
55889 if (cap = this.rules.tag.exec(src)) {
55890 if (!this.inLink && /^<a /i.test(cap[0])) {
55891 this.inLink = true;
55892 } else if (this.inLink && /^<\/a>/i.test(cap[0])) {
55893 this.inLink = false;
55895 src = src.substring(cap[0].length);
55896 out += this.options.sanitize
55897 ? this.options.sanitizer
55898 ? this.options.sanitizer(cap[0])
55905 if (cap = this.rules.link.exec(src)) {
55906 src = src.substring(cap[0].length);
55907 this.inLink = true;
55908 out += this.outputLink(cap, {
55912 this.inLink = false;
55917 if ((cap = this.rules.reflink.exec(src))
55918 || (cap = this.rules.nolink.exec(src))) {
55919 src = src.substring(cap[0].length);
55920 link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
55921 link = this.links[link.toLowerCase()];
55922 if (!link || !link.href) {
55923 out += cap[0].charAt(0);
55924 src = cap[0].substring(1) + src;
55927 this.inLink = true;
55928 out += this.outputLink(cap, link);
55929 this.inLink = false;
55934 if (cap = this.rules.strong.exec(src)) {
55935 src = src.substring(cap[0].length);
55936 out += this.renderer.strong(this.output(cap[2] || cap[1]));
55941 if (cap = this.rules.em.exec(src)) {
55942 src = src.substring(cap[0].length);
55943 out += this.renderer.em(this.output(cap[2] || cap[1]));
55948 if (cap = this.rules.code.exec(src)) {
55949 src = src.substring(cap[0].length);
55950 out += this.renderer.codespan(escape(cap[2], true));
55955 if (cap = this.rules.br.exec(src)) {
55956 src = src.substring(cap[0].length);
55957 out += this.renderer.br();
55962 if (cap = this.rules.del.exec(src)) {
55963 src = src.substring(cap[0].length);
55964 out += this.renderer.del(this.output(cap[1]));
55969 if (cap = this.rules.text.exec(src)) {
55970 src = src.substring(cap[0].length);
55971 out += this.renderer.text(escape(this.smartypants(cap[0])));
55977 Error('Infinite loop on byte: ' + src.charCodeAt(0));
55988 InlineLexer.prototype.outputLink = function(cap, link) {
55989 var href = escape(link.href)
55990 , title = link.title ? escape(link.title) : null;
55992 return cap[0].charAt(0) !== '!'
55993 ? this.renderer.link(href, title, this.output(cap[1]))
55994 : this.renderer.image(href, title, escape(cap[1]));
55998 * Smartypants Transformations
56001 InlineLexer.prototype.smartypants = function(text) {
56002 if (!this.options.smartypants) return text;
56005 .replace(/---/g, '\u2014')
56007 .replace(/--/g, '\u2013')
56009 .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
56010 // closing singles & apostrophes
56011 .replace(/'/g, '\u2019')
56013 .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
56015 .replace(/"/g, '\u201d')
56017 .replace(/\.{3}/g, '\u2026');
56024 InlineLexer.prototype.mangle = function(text) {
56025 if (!this.options.mangle) return text;
56031 for (; i < l; i++) {
56032 ch = text.charCodeAt(i);
56033 if (Math.random() > 0.5) {
56034 ch = 'x' + ch.toString(16);
56036 out += '&#' + ch + ';';
56046 function Renderer(options) {
56047 this.options = options || {};
56050 Renderer.prototype.code = function(code, lang, escaped) {
56051 if (this.options.highlight) {
56052 var out = this.options.highlight(code, lang);
56053 if (out != null && out !== code) {
56060 return '<pre><code>'
56061 + (escaped ? code : escape(code, true))
56062 + '\n</code></pre>';
56065 return '<pre><code class="'
56066 + this.options.langPrefix
56067 + escape(lang, true)
56069 + (escaped ? code : escape(code, true))
56070 + '\n</code></pre>\n';
56073 Renderer.prototype.blockquote = function(quote) {
56074 return '<blockquote>\n' + quote + '</blockquote>\n';
56077 Renderer.prototype.html = function(html) {
56081 Renderer.prototype.heading = function(text, level, raw) {
56085 + this.options.headerPrefix
56086 + raw.toLowerCase().replace(/[^\w]+/g, '-')
56094 Renderer.prototype.hr = function() {
56095 return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
56098 Renderer.prototype.list = function(body, ordered) {
56099 var type = ordered ? 'ol' : 'ul';
56100 return '<' + type + '>\n' + body + '</' + type + '>\n';
56103 Renderer.prototype.listitem = function(text) {
56104 return '<li>' + text + '</li>\n';
56107 Renderer.prototype.paragraph = function(text) {
56108 return '<p>' + text + '</p>\n';
56111 Renderer.prototype.table = function(header, body) {
56122 Renderer.prototype.tablerow = function(content) {
56123 return '<tr>\n' + content + '</tr>\n';
56126 Renderer.prototype.tablecell = function(content, flags) {
56127 var type = flags.header ? 'th' : 'td';
56128 var tag = flags.align
56129 ? '<' + type + ' style="text-align:' + flags.align + '">'
56130 : '<' + type + '>';
56131 return tag + content + '</' + type + '>\n';
56134 // span level renderer
56135 Renderer.prototype.strong = function(text) {
56136 return '<strong>' + text + '</strong>';
56139 Renderer.prototype.em = function(text) {
56140 return '<em>' + text + '</em>';
56143 Renderer.prototype.codespan = function(text) {
56144 return '<code>' + text + '</code>';
56147 Renderer.prototype.br = function() {
56148 return this.options.xhtml ? '<br/>' : '<br>';
56151 Renderer.prototype.del = function(text) {
56152 return '<del>' + text + '</del>';
56155 Renderer.prototype.link = function(href, title, text) {
56156 if (this.options.sanitize) {
56158 var prot = decodeURIComponent(unescape(href))
56159 .replace(/[^\w:]/g, '')
56164 if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0) {
56168 var out = '<a href="' + href + '"';
56170 out += ' title="' + title + '"';
56172 out += '>' + text + '</a>';
56176 Renderer.prototype.image = function(href, title, text) {
56177 var out = '<img src="' + href + '" alt="' + text + '"';
56179 out += ' title="' + title + '"';
56181 out += this.options.xhtml ? '/>' : '>';
56185 Renderer.prototype.text = function(text) {
56190 * Parsing & Compiling
56193 function Parser(options) {
56196 this.options = options || marked.defaults;
56197 this.options.renderer = this.options.renderer || new Renderer;
56198 this.renderer = this.options.renderer;
56199 this.renderer.options = this.options;
56203 * Static Parse Method
56206 Parser.parse = function(src, options, renderer) {
56207 var parser = new Parser(options, renderer);
56208 return parser.parse(src);
56215 Parser.prototype.parse = function(src) {
56216 this.inline = new InlineLexer(src.links, this.options, this.renderer);
56217 this.tokens = src.reverse();
56220 while (this.next()) {
56231 Parser.prototype.next = function() {
56232 return this.token = this.tokens.pop();
56236 * Preview Next Token
56239 Parser.prototype.peek = function() {
56240 return this.tokens[this.tokens.length - 1] || 0;
56244 * Parse Text Tokens
56247 Parser.prototype.parseText = function() {
56248 var body = this.token.text;
56250 while (this.peek().type === 'text') {
56251 body += '\n' + this.next().text;
56254 return this.inline.output(body);
56258 * Parse Current Token
56261 Parser.prototype.tok = function() {
56262 switch (this.token.type) {
56267 return this.renderer.hr();
56270 return this.renderer.heading(
56271 this.inline.output(this.token.text),
56276 return this.renderer.code(this.token.text,
56278 this.token.escaped);
56291 for (i = 0; i < this.token.header.length; i++) {
56292 flags = { header: true, align: this.token.align[i] };
56293 cell += this.renderer.tablecell(
56294 this.inline.output(this.token.header[i]),
56295 { header: true, align: this.token.align[i] }
56298 header += this.renderer.tablerow(cell);
56300 for (i = 0; i < this.token.cells.length; i++) {
56301 row = this.token.cells[i];
56304 for (j = 0; j < row.length; j++) {
56305 cell += this.renderer.tablecell(
56306 this.inline.output(row[j]),
56307 { header: false, align: this.token.align[j] }
56311 body += this.renderer.tablerow(cell);
56313 return this.renderer.table(header, body);
56315 case 'blockquote_start': {
56318 while (this.next().type !== 'blockquote_end') {
56319 body += this.tok();
56322 return this.renderer.blockquote(body);
56324 case 'list_start': {
56326 , ordered = this.token.ordered;
56328 while (this.next().type !== 'list_end') {
56329 body += this.tok();
56332 return this.renderer.list(body, ordered);
56334 case 'list_item_start': {
56337 while (this.next().type !== 'list_item_end') {
56338 body += this.token.type === 'text'
56343 return this.renderer.listitem(body);
56345 case 'loose_item_start': {
56348 while (this.next().type !== 'list_item_end') {
56349 body += this.tok();
56352 return this.renderer.listitem(body);
56355 var html = !this.token.pre && !this.options.pedantic
56356 ? this.inline.output(this.token.text)
56358 return this.renderer.html(html);
56360 case 'paragraph': {
56361 return this.renderer.paragraph(this.inline.output(this.token.text));
56364 return this.renderer.paragraph(this.parseText());
56373 function escape(html, encode) {
56375 .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&')
56376 .replace(/</g, '<')
56377 .replace(/>/g, '>')
56378 .replace(/"/g, '"')
56379 .replace(/'/g, ''');
56382 function unescape(html) {
56383 // explicitly match decimal, hex, and named HTML entities
56384 return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/g, function(_, n) {
56385 n = n.toLowerCase();
56386 if (n === 'colon') return ':';
56387 if (n.charAt(0) === '#') {
56388 return n.charAt(1) === 'x'
56389 ? String.fromCharCode(parseInt(n.substring(2), 16))
56390 : String.fromCharCode(+n.substring(1));
56396 function replace(regex, opt) {
56397 regex = regex.source;
56399 return function self(name, val) {
56400 if (!name) return new RegExp(regex, opt);
56401 val = val.source || val;
56402 val = val.replace(/(^|[^\[])\^/g, '$1');
56403 regex = regex.replace(name, val);
56411 function merge(obj) {
56416 for (; i < arguments.length; i++) {
56417 target = arguments[i];
56418 for (key in target) {
56419 if (Object.prototype.hasOwnProperty.call(target, key)) {
56420 obj[key] = target[key];
56433 function marked(src, opt, callback) {
56434 if (callback || typeof opt === 'function') {
56440 opt = merge({}, marked.defaults, opt || {});
56442 var highlight = opt.highlight
56448 tokens = Lexer.lex(src, opt);
56450 return callback(e);
56453 pending = tokens.length;
56455 var done = function(err) {
56457 opt.highlight = highlight;
56458 return callback(err);
56464 out = Parser.parse(tokens, opt);
56469 opt.highlight = highlight;
56473 : callback(null, out);
56476 if (!highlight || highlight.length < 3) {
56480 delete opt.highlight;
56482 if (!pending) return done();
56484 for (; i < tokens.length; i++) {
56486 if (token.type !== 'code') {
56487 return --pending || done();
56489 return highlight(token.text, token.lang, function(err, code) {
56490 if (err) return done(err);
56491 if (code == null || code === token.text) {
56492 return --pending || done();
56495 token.escaped = true;
56496 --pending || done();
56504 if (opt) opt = merge({}, marked.defaults, opt);
56505 return Parser.parse(Lexer.lex(src, opt), opt);
56507 e.message += '\nPlease report this to https://github.com/chjj/marked.';
56508 if ((opt || marked.defaults).silent) {
56509 return '<p>An error occured:</p><pre>'
56510 + escape(e.message + '', true)
56522 marked.setOptions = function(opt) {
56523 merge(marked.defaults, opt);
56527 marked.defaults = {
56538 langPrefix: 'lang-',
56539 smartypants: false,
56541 renderer: new Renderer,
56549 marked.Parser = Parser;
56550 marked.parser = Parser.parse;
56552 marked.Renderer = Renderer;
56554 marked.Lexer = Lexer;
56555 marked.lexer = Lexer.lex;
56557 marked.InlineLexer = InlineLexer;
56558 marked.inlineLexer = InlineLexer.output;
56560 marked.parse = marked;
56562 if (typeof module !== 'undefined' && typeof exports === 'object') {
56563 module.exports = marked;
56564 } else if (typeof define === 'function' && define.amd) {
56565 define(function() { return marked; });
56567 this.marked = marked;
56570 }).call(function() {
56571 return this || (typeof window !== 'undefined' ? window : commonjsGlobal);
56575 // toggles the visibility of ui elements, using a combination of the
56576 // hide class, which sets display=none, and a d3 transition for opacity.
56577 // this will cause blinking when called repeatedly, so check that the
56578 // value actually changes between calls.
56579 function uiToggle(show, callback) {
56580 return function(selection$$1) {
56582 .style('opacity', show ? 0 : 1)
56583 .classed('hide', false)
56585 .style('opacity', show ? 1 : 0)
56586 .on('end', function() {
56588 .classed('hide', !show)
56589 .style('opacity', null);
56590 if (callback) callback.apply(this);
56595 // Tooltips and svg mask used to highlight certain features
56596 function d3curtain() {
56598 var dispatch$$1 = dispatch(),
56599 surface = select(null),
56600 tooltip = select(null),
56601 darkness = select(null);
56603 function curtain(selection$$1) {
56604 surface = selection$$1
56606 .attr('id', 'curtain')
56607 .style('z-index', 1000)
56608 .style('pointer-events', 'none')
56609 .style('position', 'absolute')
56613 darkness = surface.append('path')
56616 .attr('class', 'curtain-darkness');
56618 select(window).on('resize.curtain', resize);
56620 tooltip = selection$$1.append('div')
56621 .attr('class', 'tooltip')
56622 .style('z-index', 1002);
56626 .attr('class', 'tooltip-arrow');
56630 .attr('class', 'tooltip-inner');
56635 function resize() {
56637 .attr('width', window.innerWidth)
56638 .attr('height', window.innerHeight);
56639 curtain.cut(darkness.datum());
56644 curtain.reveal = function(box, text$$1, tooltipclass, duration) {
56645 if (typeof box === 'string') box = select(box).node();
56646 if (box.getBoundingClientRect) box = box.getBoundingClientRect();
56648 curtain.cut(box, duration);
56651 // pseudo markdown bold text hack
56652 var parts = text$$1.split('**');
56653 var html$$1 = parts[0] ? '<span>' + parts[0] + '</span>' : '';
56654 if (parts[1]) html$$1 += '<span class="bold">' + parts[1] + '</span>';
56656 var selection$$1 = tooltip
56657 .classed('in', true)
56658 .selectAll('.tooltip-inner')
56661 var dimensions = utilGetDimensions(selection$$1, true),
56662 w = window.innerWidth,
56663 h = window.innerHeight,
56666 // trim box dimensions to just the portion that fits in the window..
56667 if (box.top + box.height > h) {
56668 box.height -= (box.top + box.height - h);
56670 if (box.left + box.width > w) {
56671 box.width -= (box.left + box.width - w);
56674 // determine tooltip placement..
56675 if (box.top + box.height < Math.min(100, box.width + box.left)) {
56677 pos = [box.left + box.width / 2 - dimensions[0] / 2, box.top + box.height];
56679 } else if (box.left + box.width + 300 < w) {
56681 pos = [box.left + box.width, box.top + box.height / 2 - dimensions[1] / 2];
56683 } else if (box.left > 300) {
56685 pos = [box.left - 200, box.top + box.height / 2 - dimensions[1] / 2];
56689 pos = [box.left, box.top + box.height];
56693 Math.min(Math.max(10, pos[0]), w - dimensions[0] - 10),
56694 Math.min(Math.max(10, pos[1]), h - dimensions[1] - 10)
56697 if (duration !== 0 || !tooltip.classed(side)) {
56698 tooltip.call(uiToggle(true));
56702 .style('top', pos[1] + 'px')
56703 .style('left', pos[0] + 'px')
56704 .attr('class', 'curtain-tooltip tooltip in ' + side + ' ' + tooltipclass);
56707 tooltip.call(uiToggle(false));
56712 curtain.cut = function(datum, duration) {
56713 darkness.datum(datum)
56716 (duration === 0 ? darkness : darkness.transition().duration(duration || 600))
56717 .attr('d', function(d) {
56718 var string = 'M 0,0 L 0,' + window.innerHeight + ' L ' +
56719 window.innerWidth + ',' + window.innerHeight + 'L' +
56720 window.innerWidth + ',0 Z';
56722 if (!d) return string;
56723 return string + 'M' +
56724 d.left + ',' + d.top + 'L' +
56725 d.left + ',' + (d.top + d.height) + 'L' +
56726 (d.left + d.width) + ',' + (d.top + d.height) + 'L' +
56727 (d.left + d.width) + ',' + (d.top) + 'Z';
56733 curtain.remove = function() {
56739 return utilRebind(curtain, dispatch$$1, 'on');
56742 var dataIntroGraph = {"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]},"n185964961":{"id":"n185964961","loc":[-85.6406588,41.942601]},"n185964962":{"id":"n185964962","loc":[-85.6394548,41.94261]},"n185970607":{"id":"n185970607","loc":[-85.641094,41.94006]},"n185970614":{"id":"n185970614","loc":[-85.641825,41.941316]},"n185970616":{"id":"n185970616","loc":[-85.641838,41.941556]},"n185973650":{"id":"n185973650","loc":[-85.639918,41.940064]},"n185973660":{"id":"n185973660","loc":[-85.640645,41.941339]},"n185973659":{"id":"n185973659","loc":[-85.6406115,41.9400658]},"n185974479":{"id":"n185974479","loc":[-85.639402,41.941344]},"n185974481":{"id":"n185974481","loc":[-85.643071,41.941288]},"n185976259":{"id":"n185976259","loc":[-85.642213,41.940043]},"n185976261":{"id":"n185976261","loc":[-85.643056,41.94001]},"n185964959":{"id":"n185964959","loc":[-85.6431031,41.9425754]},"n185964960":{"id":"n185964960","loc":[-85.6418749,41.9425864]},"n185981481":{"id":"n185981481","loc":[-85.6386827,41.9400828]},"n185981482":{"id":"n185981482","loc":[-85.6393664,41.9400854]},"n2138493844":{"id":"n2138493844","loc":[-85.6427969,41.940522]},"n2138493845":{"id":"n2138493845","loc":[-85.6425891,41.9405228]},"n2138493846":{"id":"n2138493846","loc":[-85.6425868,41.9402875]},"n2138493847":{"id":"n2138493847","loc":[-85.6427969,41.9402858]},"n2138493848":{"id":"n2138493848","loc":[-85.6425708,41.9405234]},"n2138493849":{"id":"n2138493849","loc":[-85.642568,41.9402855]},"n2138493850":{"id":"n2138493850","loc":[-85.6423157,41.9402886]},"n2138493851":{"id":"n2138493851","loc":[-85.6423212,41.9404362]},"n2138493852":{"id":"n2138493852","loc":[-85.6422923,41.9404578]},"n2138493853":{"id":"n2138493853","loc":[-85.6422868,41.9404834]},"n2138493854":{"id":"n2138493854","loc":[-85.6423226,41.9405091]},"n2138493855":{"id":"n2138493855","loc":[-85.6423847,41.9405111]},"n2138493856":{"id":"n2138493856","loc":[-85.6424081,41.9405265]},"n2140155811":{"id":"n2140155811","loc":[-85.6419547,41.9410956]},"n2140155814":{"id":"n2140155814","loc":[-85.6427577,41.9410884]},"n2140155816":{"id":"n2140155816","loc":[-85.6427545,41.9410052]},"n2140155818":{"id":"n2140155818","loc":[-85.6428057,41.9410028]},"n2140155821":{"id":"n2140155821","loc":[-85.6427993,41.9407339]},"n2140155823":{"id":"n2140155823","loc":[-85.6427385,41.9407339]},"n2140155825":{"id":"n2140155825","loc":[-85.6427417,41.9406435]},"n2140155827":{"id":"n2140155827","loc":[-85.6419515,41.9406482]},"n2140155828":{"id":"n2140155828","loc":[-85.6429368,41.9412407]},"n2140155829":{"id":"n2140155829","loc":[-85.6417756,41.9412526]},"n2140155830":{"id":"n2140155830","loc":[-85.641766,41.9405983]},"n2140155831":{"id":"n2140155831","loc":[-85.6419803,41.9405983]},"n2140155832":{"id":"n2140155832","loc":[-85.6419611,41.9401366]},"n2140155833":{"id":"n2140155833","loc":[-85.6429336,41.94012]},"n2140155834":{"id":"n2140155834","loc":[-85.6430697,41.9411732]},"n2140155835":{"id":"n2140155835","loc":[-85.6428411,41.9409974]},"n2140155837":{"id":"n2140155837","loc":[-85.6428388,41.9407211]},"n2140155839":{"id":"n2140155839","loc":[-85.6430624,41.9405521]},"n2140155840":{"id":"n2140155840","loc":[-85.6427323,41.9412396]},"n2140155842":{"id":"n2140155842","loc":[-85.6418147,41.9412457]},"n2140155844":{"id":"n2140155844","loc":[-85.641813,41.9411319]},"n2140155845":{"id":"n2140155845","loc":[-85.6418394,41.9411111]},"n2140155847":{"id":"n2140155847","loc":[-85.6418838,41.9410977]},"n2140155849":{"id":"n2140155849","loc":[-85.6427324,41.9410921]},"n2140155851":{"id":"n2140155851","loc":[-85.6427798,41.9412945]},"n2140155852":{"id":"n2140155852","loc":[-85.6427701,41.9411777]},"n2140155854":{"id":"n2140155854","loc":[-85.6427323,41.9411572]},"n2140155856":{"id":"n2140155856","loc":[-85.6418478,41.9411666]},"n2165942818":{"id":"n2165942818","loc":[-85.6437533,41.9415029]},"n2165942819":{"id":"n2165942819","loc":[-85.6437623,41.9421195]},"n2168510551":{"id":"n2168510551","loc":[-85.6423795,41.9422615]},"n2168510552":{"id":"n2168510552","loc":[-85.6423744,41.9419439]},"n2168510553":{"id":"n2168510553","loc":[-85.642518,41.9419427]},"n2168510554":{"id":"n2168510554","loc":[-85.6425186,41.9419801]},"n2168510555":{"id":"n2168510555","loc":[-85.6428314,41.9419773]},"n2168510556":{"id":"n2168510556","loc":[-85.6428368,41.9423116]},"n2168510557":{"id":"n2168510557","loc":[-85.6424947,41.9423146]},"n2168510558":{"id":"n2168510558","loc":[-85.6424938,41.9422605]},"n2189046007":{"id":"n2189046007","loc":[-85.6410866,41.9424327]},"n2189046009":{"id":"n2189046009","loc":[-85.6410805,41.9420061]},"n2189046011":{"id":"n2189046011","loc":[-85.6412443,41.9420048]},"n2189046012":{"id":"n2189046012","loc":[-85.6412505,41.9424314]},"n2189046014":{"id":"n2189046014","loc":[-85.6413311,41.942968]},"n2189046016":{"id":"n2189046016","loc":[-85.6413281,41.942713]},"n2189046018":{"id":"n2189046018","loc":[-85.641521,41.9427117]},"n2189046021":{"id":"n2189046021","loc":[-85.6415234,41.9429236]},"n2189046022":{"id":"n2189046022","loc":[-85.6415045,41.9429238]},"n2189046025":{"id":"n2189046025","loc":[-85.641505,41.9429668]},"n2189046053":{"id":"n2189046053","loc":[-85.6385988,41.942412]},"n2189046054":{"id":"n2189046054","loc":[-85.6385985,41.9423311]},"n2189046055":{"id":"n2189046055","loc":[-85.6387617,41.9423308]},"n2189046056":{"id":"n2189046056","loc":[-85.6387616,41.9423026]},"n2189046058":{"id":"n2189046058","loc":[-85.6388215,41.9423025]},"n2189046059":{"id":"n2189046059","loc":[-85.6388219,41.9424115]},"n2189046060":{"id":"n2189046060","loc":[-85.6391096,41.9424486]},"n2189046061":{"id":"n2189046061","loc":[-85.6391105,41.9423673]},"n2189046063":{"id":"n2189046063","loc":[-85.6392911,41.9423684]},"n2189046065":{"id":"n2189046065","loc":[-85.6392903,41.9424497]},"n2189046067":{"id":"n2189046067","loc":[-85.6397927,41.9423876]},"n2189046069":{"id":"n2189046069","loc":[-85.6397897,41.9422981]},"n2189046070":{"id":"n2189046070","loc":[-85.6399702,41.9422947]},"n2189046072":{"id":"n2189046072","loc":[-85.6399732,41.9423843]},"n2189046074":{"id":"n2189046074","loc":[-85.6396331,41.9430227]},"n2189046075":{"id":"n2189046075","loc":[-85.6398673,41.9430189]},"n2189046077":{"id":"n2189046077","loc":[-85.6398656,41.9429637]},"n2189046079":{"id":"n2189046079","loc":[-85.6398885,41.9429633]},"n2189046082":{"id":"n2189046082","loc":[-85.6398832,41.942779]},"n2189046083":{"id":"n2189046083","loc":[-85.6398513,41.9427796]},"n2189046085":{"id":"n2189046085","loc":[-85.6398502,41.9427401]},"n2189046087":{"id":"n2189046087","loc":[-85.6397889,41.9427411]},"n2189046089":{"id":"n2189046089","loc":[-85.6397892,41.942753]},"n2189046090":{"id":"n2189046090","loc":[-85.6396983,41.9427544]},"n2189046092":{"id":"n2189046092","loc":[-85.6396993,41.9427882]},"n2189046094":{"id":"n2189046094","loc":[-85.6396746,41.9427886]},"n2189046096":{"id":"n2189046096","loc":[-85.6396758,41.9428296]},"n2189046097":{"id":"n2189046097","loc":[-85.6397007,41.9428292]},"n2189046099":{"id":"n2189046099","loc":[-85.6397018,41.9428686]},"n2189046103":{"id":"n2189046103","loc":[-85.6396289,41.9428697]},"n2189046112":{"id":"n2189046112","loc":[-85.6435683,41.9429457]},"n2189046113":{"id":"n2189046113","loc":[-85.643568,41.9427766]},"n2189046115":{"id":"n2189046115","loc":[-85.6434011,41.9427767]},"n2189046116":{"id":"n2189046116","loc":[-85.6434012,41.9428631]},"n2189046117":{"id":"n2189046117","loc":[-85.643448,41.9428631]},"n2189046118":{"id":"n2189046118","loc":[-85.6434481,41.9429457]},"n2189046119":{"id":"n2189046119","loc":[-85.6428363,41.9429809]},"n2189046120":{"id":"n2189046120","loc":[-85.6429171,41.9429791]},"n2189046121":{"id":"n2189046121","loc":[-85.642914,41.9429041]},"n2189046122":{"id":"n2189046122","loc":[-85.6429385,41.9429035]},"n2189046123":{"id":"n2189046123","loc":[-85.6429348,41.9428126]},"n2189046124":{"id":"n2189046124","loc":[-85.6427746,41.9428163]},"n2189046125":{"id":"n2189046125","loc":[-85.6427783,41.942906]},"n2189046126":{"id":"n2189046126","loc":[-85.6428332,41.9429047]},"n2189046127":{"id":"n2189046127","loc":[-85.6423018,41.9428859]},"n2189046128":{"id":"n2189046128","loc":[-85.6422987,41.9427208]},"n2189046130":{"id":"n2189046130","loc":[-85.6424218,41.9427195]},"n2189046131":{"id":"n2189046131","loc":[-85.6424246,41.9428684]},"n2189046132":{"id":"n2189046132","loc":[-85.6423845,41.9428689]},"n2189046133":{"id":"n2189046133","loc":[-85.6423848,41.942885]},"n2189046134":{"id":"n2189046134","loc":[-85.641533,41.9429392]},"n2189046135":{"id":"n2189046135","loc":[-85.6416096,41.9428768]},"n2189046137":{"id":"n2189046137","loc":[-85.6416763,41.9429221]},"n2189046138":{"id":"n2189046138","loc":[-85.6415997,41.9429845]},"n2189046139":{"id":"n2189046139","loc":[-85.6420598,41.9428016]},"n2189046140":{"id":"n2189046140","loc":[-85.6420593,41.9427415]},"n2189046141":{"id":"n2189046141","loc":[-85.6421957,41.9427409]},"n2189046142":{"id":"n2189046142","loc":[-85.6421963,41.9428182]},"n2189046143":{"id":"n2189046143","loc":[-85.6421281,41.9428185]},"n2189046144":{"id":"n2189046144","loc":[-85.6421279,41.9428013]},"n2189046145":{"id":"n2189046145","loc":[-85.6409429,41.9429345]},"n2189046146":{"id":"n2189046146","loc":[-85.6410354,41.9429334]},"n2189046147":{"id":"n2189046147","loc":[-85.6410325,41.9427972]},"n2189046148":{"id":"n2189046148","loc":[-85.640997,41.9427976]},"n2189046149":{"id":"n2189046149","loc":[-85.6409963,41.9427643]},"n2189046150":{"id":"n2189046150","loc":[-85.6408605,41.9427659]},"n2189046152":{"id":"n2189046152","loc":[-85.6408623,41.9428482]},"n2189046153":{"id":"n2189046153","loc":[-85.640941,41.9428473]},"n2189152992":{"id":"n2189152992","loc":[-85.6437661,41.9422257]},"n2189152993":{"id":"n2189152993","loc":[-85.643768,41.9424067]},"n2189152994":{"id":"n2189152994","loc":[-85.6432176,41.9417705]},"n2189152995":{"id":"n2189152995","loc":[-85.6432097,41.941327]},"n2189152996":{"id":"n2189152996","loc":[-85.6436493,41.9413226]},"n2189152997":{"id":"n2189152997","loc":[-85.6436563,41.9417164]},"n2189152998":{"id":"n2189152998","loc":[-85.6435796,41.9417171]},"n2189152999":{"id":"n2189152999","loc":[-85.6435805,41.9417669]},"n2189153000":{"id":"n2189153000","loc":[-85.6438202,41.9414953]},"n2189153001":{"id":"n2189153001","loc":[-85.6438173,41.9413175]},"n2189153004":{"id":"n2189153004","loc":[-85.6432535,41.9418466]},"n2189153005":{"id":"n2189153005","loc":[-85.6433935,41.9418599]},"n2189153006":{"id":"n2189153006","loc":[-85.6434831,41.9418986]},"n2189153007":{"id":"n2189153007","loc":[-85.6435678,41.9419774]},"n2189153008":{"id":"n2189153008","loc":[-85.6435987,41.9420282]},"n2189153009":{"id":"n2189153009","loc":[-85.643438,41.9419573]},"n2189153010":{"id":"n2189153010","loc":[-85.6435284,41.9424676]},"n2189153011":{"id":"n2189153011","loc":[-85.6436207,41.9423631]},"n2189153012":{"id":"n2189153012","loc":[-85.6434957,41.9422973]},"n2189153013":{"id":"n2189153013","loc":[-85.6434457,41.9422458]},"n2189153014":{"id":"n2189153014","loc":[-85.6433976,41.9421772]},"n2189153015":{"id":"n2189153015","loc":[-85.6433861,41.9420785]},"n2189153016":{"id":"n2189153016","loc":[-85.6433765,41.9420313]},"n2189153017":{"id":"n2189153017","loc":[-85.6432207,41.9420284]},"n2189153018":{"id":"n2189153018","loc":[-85.6432245,41.9422759]},"n2189153019":{"id":"n2189153019","loc":[-85.6432649,41.9423474]},"n2189153020":{"id":"n2189153020","loc":[-85.6433226,41.9424132]},"n2189153021":{"id":"n2189153021","loc":[-85.6434111,41.9424704]},"n2189153022":{"id":"n2189153022","loc":[-85.6434591,41.9424347]},"n2189153025":{"id":"n2189153025","loc":[-85.6437669,41.9423073]},"n2189153026":{"id":"n2189153026","loc":[-85.6436611,41.942293]},"n2189153027":{"id":"n2189153027","loc":[-85.6435784,41.9422473]},"n2189153028":{"id":"n2189153028","loc":[-85.6435245,41.9421443]},"n2189153029":{"id":"n2189153029","loc":[-85.6435149,41.9420613]},"n2189153030":{"id":"n2189153030","loc":[-85.6433528,41.9419269]},"n2189153031":{"id":"n2189153031","loc":[-85.6432535,41.9419191]},"n2189153032":{"id":"n2189153032","loc":[-85.6430868,41.9419198]},"n2189153033":{"id":"n2189153033","loc":[-85.6434894,41.9420033]},"n2189153034":{"id":"n2189153034","loc":[-85.6432974,41.9419225]},"n2189153035":{"id":"n2189153035","loc":[-85.6433055,41.9421632]},"n2189153036":{"id":"n2189153036","loc":[-85.6433538,41.9422849]},"n2189153037":{"id":"n2189153037","loc":[-85.6434718,41.9423887]},"n2189153038":{"id":"n2189153038","loc":[-85.6436134,41.9422667]},"n2189153040":{"id":"n2189153040","loc":[-85.6438759,41.9414017]},"n2189153041":{"id":"n2189153041","loc":[-85.6438181,41.9413687]},"n2189153042":{"id":"n2189153042","loc":[-85.6436821,41.9413044]},"n2189153043":{"id":"n2189153043","loc":[-85.6435899,41.9412862]},"n2189153044":{"id":"n2189153044","loc":[-85.6433169,41.9417268]},"n2189153045":{"id":"n2189153045","loc":[-85.643301,41.9412859]},"n2189153046":{"id":"n2189153046","loc":[-85.6435531,41.9416981]},"n2189153047":{"id":"n2189153047","loc":[-85.6435427,41.9412863]},"n185948706":{"id":"n185948706","loc":[-85.6369439,41.940122]},"n185949348":{"id":"n185949348","loc":[-85.640039,41.931135]},"n185949870":{"id":"n185949870","loc":[-85.643195,41.949261]},"n185954680":{"id":"n185954680","loc":[-85.6337802,41.9401143]},"n185954784":{"id":"n185954784","loc":[-85.6487485,41.942527]},"n185958670":{"id":"n185958670","loc":[-85.637255,41.940104]},"n185958672":{"id":"n185958672","loc":[-85.636996,41.941355]},"n185960207":{"id":"n185960207","loc":[-85.634992,41.940118]},"n185963163":{"id":"n185963163","loc":[-85.638831,41.93398]},"n185963165":{"id":"n185963165","loc":[-85.640073,41.933968]},"n185963167":{"id":"n185963167","loc":[-85.641225,41.933972]},"n185963168":{"id":"n185963168","loc":[-85.642386,41.933952]},"n185964695":{"id":"n185964695","loc":[-85.6443608,41.9425645]},"n185964697":{"id":"n185964697","loc":[-85.644384,41.939941]},"n185964963":{"id":"n185964963","loc":[-85.6382347,41.9426146]},"n185964965":{"id":"n185964965","loc":[-85.637022,41.942622]},"n185964967":{"id":"n185964967","loc":[-85.6363706,41.9426606]},"n185964968":{"id":"n185964968","loc":[-85.6357988,41.9427748]},"n185964969":{"id":"n185964969","loc":[-85.6355409,41.9428465]},"n185964970":{"id":"n185964970","loc":[-85.6348729,41.9430443]},"n185966958":{"id":"n185966958","loc":[-85.641946,41.946413]},"n185966960":{"id":"n185966960","loc":[-85.643148,41.946389]},"n185967774":{"id":"n185967774","loc":[-85.641889,41.943852]},"n185967775":{"id":"n185967775","loc":[-85.641922,41.945121]},"n185967776":{"id":"n185967776","loc":[-85.641927,41.947544]},"n185967777":{"id":"n185967777","loc":[-85.641982,41.947622]},"n185969289":{"id":"n185969289","loc":[-85.63928,41.929221]},"n185969704":{"id":"n185969704","loc":[-85.6388186,41.9350099]},"n185969706":{"id":"n185969706","loc":[-85.6400709,41.9349957]},"n185969708":{"id":"n185969708","loc":[-85.6412214,41.9349827]},"n185969710":{"id":"n185969710","loc":[-85.6423509,41.934974]},"n185970602":{"id":"n185970602","loc":[-85.641293,41.931817]},"n185970604":{"id":"n185970604","loc":[-85.641258,41.932705]},"n185970605":{"id":"n185970605","loc":[-85.641148,41.936984]},"n185970606":{"id":"n185970606","loc":[-85.641112,41.938169]},"n185970906":{"id":"n185970906","loc":[-85.639454,41.943871]},"n185970908":{"id":"n185970908","loc":[-85.6394635,41.9450504]},"n185970909":{"id":"n185970909","loc":[-85.6394914,41.9451911]},"n185971368":{"id":"n185971368","loc":[-85.635769,41.940122]},"n185971978":{"id":"n185971978","loc":[-85.640003,41.936988]},"n185971980":{"id":"n185971980","loc":[-85.642299,41.936988]},"n185973633":{"id":"n185973633","loc":[-85.639023,41.92861]},"n185973635":{"id":"n185973635","loc":[-85.639153,41.928969]},"n185973637":{"id":"n185973637","loc":[-85.639213,41.929088]},"n185973639":{"id":"n185973639","loc":[-85.63935,41.929396]},"n185973641":{"id":"n185973641","loc":[-85.640143,41.931462]},"n185973644":{"id":"n185973644","loc":[-85.64019,41.931788]},"n185973646":{"id":"n185973646","loc":[-85.6401365,41.9327199]},"n185973648":{"id":"n185973648","loc":[-85.639983,41.938174]},"n185974477":{"id":"n185974477","loc":[-85.638206,41.941331]},"n185975928":{"id":"n185975928","loc":[-85.640683,41.94513]},"n185975930":{"id":"n185975930","loc":[-85.643102,41.945103]},"n185976255":{"id":"n185976255","loc":[-85.642424,41.931817]},"n185976257":{"id":"n185976257","loc":[-85.64242,41.932699]},"n185976258":{"id":"n185976258","loc":[-85.6422621,41.9381489]},"n185977452":{"id":"n185977452","loc":[-85.6457497,41.9398834]},"n185978772":{"id":"n185978772","loc":[-85.646656,41.939869]},"n185981472":{"id":"n185981472","loc":[-85.6388962,41.9321266]},"n185981474":{"id":"n185981474","loc":[-85.6388769,41.9327334]},"n185981476":{"id":"n185981476","loc":[-85.638829,41.934116]},"n185981478":{"id":"n185981478","loc":[-85.63876,41.937002]},"n185981480":{"id":"n185981480","loc":[-85.638682,41.93819]},"n185981999":{"id":"n185981999","loc":[-85.638194,41.9400866]},"n185982001":{"id":"n185982001","loc":[-85.646302,41.93988]},"n185982877":{"id":"n185982877","loc":[-85.640676,41.943867]},"n185982879":{"id":"n185982879","loc":[-85.640734,41.945887]},"n185985823":{"id":"n185985823","loc":[-85.643106,41.943841]},"n185985824":{"id":"n185985824","loc":[-85.643145,41.947641]},"n185985825":{"id":"n185985825","loc":[-85.643219,41.950829]},"n1475301385":{"id":"n1475301385","loc":[-85.6360612,41.9427042]},"n1475301397":{"id":"n1475301397","loc":[-85.6366651,41.9426328]},"n2139795811":{"id":"n2139795811","loc":[-85.6469154,41.9425427]},"n2139795830":{"id":"n2139795830","loc":[-85.6443194,41.9399444]},"n2139795834":{"id":"n2139795834","loc":[-85.6453506,41.9399002]},"n2139795837":{"id":"n2139795837","loc":[-85.645806,41.9398831]},"n2139858932":{"id":"n2139858932","loc":[-85.6351721,41.9429557]},"n2140019000":{"id":"n2140019000","loc":[-85.6359935,41.9427224]},"n2165942817":{"id":"n2165942817","loc":[-85.6442017,41.9414993]},"n2165942820":{"id":"n2165942820","loc":[-85.6442107,41.9421159]},"n2189152990":{"id":"n2189152990","loc":[-85.6442328,41.942404]},"n2189152991":{"id":"n2189152991","loc":[-85.6442309,41.9422229]},"n2189153002":{"id":"n2189153002","loc":[-85.6441329,41.9413147]},"n2189153003":{"id":"n2189153003","loc":[-85.6441357,41.9414925]},"n2189153023":{"id":"n2189153023","loc":[-85.6443453,41.9423074]},"n2189153024":{"id":"n2189153024","loc":[-85.6442318,41.9423045]},"n2189153039":{"id":"n2189153039","loc":[-85.6441343,41.9414025]},"w208643102":{"id":"w208643102","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2189153034","n2189153035","n2189153036","n2189153037","n2189153038"]},"w17966942":{"id":"w17966942","tags":{"highway":"residential","name":"Millard St"},"nodes":["n185954680","n185960207","n185971368","n185948706","n185958670","n185981999","n185981481","n185981482","n185973650","n185973659","n185970607","n185976259","n185976261","n2139795830","n185964697","n2139795834","n185977452","n2139795837","n185982001","n185978772"]},"w208643105":{"id":"w208643105","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2189153046","n2189153047"]},"w208631637":{"id":"w208631637","tags":{"area":"yes","building":"yes"},"nodes":["n2189046014","n2189046016","n2189046018","n2189046021","n2189046022","n2189046025","n2189046014"]},"w208643096":{"id":"w208643096","tags":{"amenity":"parking","area":"yes","fee":"no"},"nodes":["n2189152990","n2189153024","n2189152991","n2189152992","n2189153025","n2189152993","n2189152990"]},"w208631656":{"id":"w208631656","tags":{"area":"yes","building":"yes"},"nodes":["n2189046134","n2189046135","n2189046137","n2189046138","n2189046134"]},"w204003417":{"id":"w204003417","tags":{"area":"yes","building":"school"},"nodes":["n2140155811","n2140155814","n2140155816","n2140155818","n2140155821","n2140155823","n2140155825","n2140155827","n2140155811"]},"w208631654":{"id":"w208631654","tags":{"area":"yes","building":"yes"},"nodes":["n2189046127","n2189046128","n2189046130","n2189046131","n2189046132","n2189046133","n2189046127"]},"w17966327":{"id":"w17966327","tags":{"highway":"residential","name":"S Douglas Ave"},"nodes":["n185976261","n2140155839","n2140155834","n185974481","n2189153032","n185964959"]},"w41785752":{"id":"w41785752","tags":{"highway":"primary","name":"West Michigan Avenue","old_ref":"US 131","ref":"US 131 Business;M 60","access":"yes"},"nodes":["n185954784","n2139795811","n185964695","n185964959","n185964960","n185964961","n185964962","n185964963","n185964965","n1475301397","n185964967","n1475301385","n2140019000","n185964968","n185964969","n2139858932","n185964970"]},"w203841842":{"id":"w203841842","tags":{"area":"yes","leisure":"playground"},"nodes":["n2138493848","n2138493849","n2138493850","n2138493851","n2138493852","n2138493853","n2138493854","n2138493855","n2138493856","n2138493848"]},"w208643103":{"id":"w208643103","tags":{"highway":"service"},"nodes":["n2189153039","n2189153040","n2189153041","n2189153042","n2189153043","n2189153047","n2189153045","n185974481"]},"w208643098":{"id":"w208643098","tags":{"amenity":"parking","area":"yes"},"nodes":["n2189153000","n2189153041","n2189153001","n2189153002","n2189153039","n2189153003","n2189153000"]},"w208631646":{"id":"w208631646","tags":{"area":"yes","building":"yes"},"nodes":["n2189046067","n2189046069","n2189046070","n2189046072","n2189046067"]},"w208631653":{"id":"w208631653","tags":{"area":"yes","building":"yes"},"nodes":["n2189046119","n2189046120","n2189046121","n2189046122","n2189046123","n2189046124","n2189046125","n2189046126","n2189046119"]},"w17966041":{"id":"w17966041","tags":{"highway":"residential","name":"S Lincoln Ave"},"nodes":["n185973659","n185973660","n185964961"]},"w208631645":{"id":"w208631645","tags":{"area":"yes","building":"yes"},"nodes":["n2189046060","n2189046061","n2189046063","n2189046065","n2189046060"]},"w206803397":{"id":"w206803397","tags":{"area":"yes","building":"yes"},"nodes":["n2168510551","n2168510552","n2168510553","n2168510554","n2168510555","n2168510556","n2168510557","n2168510558","n2168510551"]},"w17965792":{"id":"w17965792","tags":{"highway":"residential","name":"N Hooker Ave"},"nodes":["n185964962","n185970906","n185970908","n185970909"]},"w208631651":{"id":"w208631651","tags":{"area":"yes","building":"yes"},"nodes":["n2189046112","n2189046113","n2189046115","n2189046116","n2189046117","n2189046118","n2189046112"]},"w208631643":{"id":"w208631643","tags":{"area":"yes","building":"yes"},"nodes":["n2189046053","n2189046054","n2189046055","n2189046056","n2189046058","n2189046059","n2189046053"]},"w17966878":{"id":"w17966878","tags":{"highway":"residential","name":"S Hooker Ave"},"nodes":["n185981472","n185981474","n185963163","n185981476","n185969704","n185981478","n185981480","n185981481"]},"w17966102":{"id":"w17966102","tags":{"highway":"residential","name":"South St"},"nodes":["n185958672","n185974477","n185974479","n185973660","n185970614"]},"w208631660":{"id":"w208631660","tags":{"area":"yes","building":"yes"},"nodes":["n2189046145","n2189046146","n2189046147","n2189046148","n2189046149","n2189046150","n2189046152","n2189046153","n2189046145"]},"w208643101":{"id":"w208643101","tags":{"highway":"service"},"nodes":["n2189153023","n2189153024","n2189153025","n2189153026","n2189153038","n2189153027","n2189153028","n2189153029","n2189153033","n2189153009","n2189153030","n2189153034","n2189153031","n2189153032"]},"w204000205":{"id":"w204000205","tags":{"highway":"residential","name":"South St","oneway":"yes"},"nodes":["n185974481","n2140155851","n185970614"]},"w203841841":{"id":"w203841841","tags":{"area":"yes","leisure":"pitch","pitch":"basketball"},"nodes":["n2138493844","n2138493845","n2138493846","n2138493847","n2138493844"]},"w17965444":{"id":"w17965444","tags":{"highway":"residential","name":"N Grant Ave"},"nodes":["n185964960","n185967774","n185967775","n185966958","n185967776","n185967777"]},"w208631648":{"id":"w208631648","tags":{"area":"yes","building":"yes"},"nodes":["n2189046074","n2189046075","n2189046077","n2189046079","n2189046082","n2189046083","n2189046085","n2189046087","n2189046089","n2189046090","n2189046092","n2189046094","n2189046096","n2189046097","n2189046099","n2189046103","n2189046074"]},"w208643100":{"id":"w208643100","tags":{"amenity":"parking","area":"yes"},"nodes":["n2189153010","n2189153011","n2189153012","n2189153013","n2189153014","n2189153015","n2189153016","n2189153017","n2189153018","n2189153019","n2189153020","n2189153021","n2189153022","n2189153010"]},"w17965749":{"id":"w17965749","tags":{"highway":"residential","name":"S Grant Ave"},"nodes":["n185970614","n185970616","n185964960"]},"w206574482":{"id":"w206574482","tags":{"amenity":"library","area":"yes","building":"yes","name":"Three Rivers Public Library"},"nodes":["n2165942817","n2165942818","n2165942819","n2165942820","n2165942817"]},"w208643097":{"id":"w208643097","tags":{"amenity":"parking","area":"yes"},"nodes":["n2189152994","n2189152995","n2189152996","n2189152997","n2189152998","n2189152999","n2189152994"]},"w17966879":{"id":"w17966879","tags":{"highway":"residential","name":"S Hooker Ave"},"nodes":["n185981482","n185974479","n185964962"]},"w17966325":{"id":"w17966325","tags":{"highway":"residential","name":"S Douglas Ave"},"nodes":["n185976255","n185976257","n185963168","n185969710","n185971980","n185976258","n185954700","n185976259"]},"w17967390":{"id":"w17967390","tags":{"highway":"residential","name":"N Douglas Ave"},"nodes":["n185964959","n185985823","n185975930","n185966960","n185985824","n185949870","n185985825"]},"w208631635":{"id":"w208631635","tags":{"area":"yes","building":"yes"},"nodes":["n2189046007","n2189046009","n2189046011","n2189046012","n2189046007"]},"w208643099":{"id":"w208643099","tags":{"amenity":"parking","area":"yes"},"nodes":["n2189153031","n2189153004","n2189153005","n2189153006","n2189153007","n2189153008","n2189153029","n2189153033","n2189153009","n2189153030","n2189153031"]},"w208631658":{"id":"w208631658","tags":{"area":"yes","building":"yes"},"nodes":["n2189046139","n2189046140","n2189046141","n2189046142","n2189046143","n2189046144","n2189046139"]},"w208643104":{"id":"w208643104","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2189153044","n2189153045"]},"w17966039":{"id":"w17966039","tags":{"highway":"residential","name":"S Lincoln Ave"},"nodes":["n185973633","n185973635","n185973637","n185969289","n185973639","n185949348","n185973641","n185973644","n185973646","n185963165","n185969706","n185971978","n185973648","n185973650"]},"w204003420":{"id":"w204003420","tags":{"amenity":"parking","area":"yes"},"nodes":["n2140155840","n2140155842","n2140155844","n2140155845","n2140155847","n2140155849","n2140155854","n2140155840"]},"w204003419":{"id":"w204003419","tags":{"highway":"service"},"nodes":["n2140155834","n2140155835","n2140155837","n2140155839"]},"w204003418":{"id":"w204003418","tags":{"amenity":"school","area":"yes","name":"Andrews Elementary School"},"nodes":["n2140155828","n2140155829","n2140155830","n2140155831","n2140155832","n2140155833","n2140155828"]},"w17965747":{"id":"w17965747","tags":{"highway":"residential","name":"S Grant Ave"},"nodes":["n185970602","n185970604","n185963167","n185969708","n185970605","n185970606","n185970607"]},"w17967073":{"id":"w17967073","tags":{"highway":"residential","name":"N Lincoln Ave"},"nodes":["n185964961","n185982877","n185975928","n185982879"]},"w204003421":{"id":"w204003421","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2140155851","n2140155852","n2140155854","n2140155856"]},"r1943857":{"id":"r1943857","tags":{"modifier":"Business","name":"US 131 Business (Three Rivers, MI)","network":"US:US","ref":"131","route":"road","type":"route"},"members":[{"id":"w17966509","type":"way","role":"forward"},{"id":"w143497377","type":"way","role":""},{"id":"w134150811","type":"way","role":""},{"id":"w134150800","type":"way","role":""},{"id":"w134150789","type":"way","role":""},{"id":"w134150795","type":"way","role":""},{"id":"w41785752","type":"way","role":""},{"id":"w17965146","type":"way","role":"forward"},{"id":"w17964031","type":"way","role":"forward"}]},"r270277":{"id":"r270277","tags":{"network":"US:MI","ref":"60","route":"road","state_id":"MI","type":"route","url":"http://en.wikipedia.org/wiki/M-60_%28Michigan_highway%29"},"members":[{"id":"w17751087","type":"way","role":"east"},{"id":"w117148312","type":"way","role":"east"},{"id":"w40942155","type":"way","role":"west"},{"id":"w17751017","type":"way","role":""},{"id":"w17751083","type":"way","role":""},{"id":"w17747780","type":"way","role":""},{"id":"w41068082","type":"way","role":""},{"id":"w197025212","type":"way","role":""},{"id":"w17743874","type":"way","role":""},{"id":"w17751044","type":"way","role":""},{"id":"w17752167","type":"way","role":""},{"id":"w17751089","type":"way","role":""},{"id":"w17743879","type":"way","role":""},{"id":"w17751064","type":"way","role":""},{"id":"w197057073","type":"way","role":""},{"id":"w167699963","type":"way","role":""},{"id":"w167699972","type":"way","role":""},{"id":"w17967584","type":"way","role":""},{"id":"w167699964","type":"way","role":""},{"id":"w17967582","type":"way","role":"west"},{"id":"w41260270","type":"way","role":"west"},{"id":"w17965146","type":"way","role":"west"},{"id":"w41785752","type":"way","role":""},{"id":"w134150795","type":"way","role":""},{"id":"w134150789","type":"way","role":""},{"id":"w134150800","type":"way","role":""},{"id":"w134150811","type":"way","role":""},{"id":"w134150836","type":"way","role":""},{"id":"w134150802","type":"way","role":""},{"id":"w41074896","type":"way","role":""},{"id":"w17966773","type":"way","role":""},{"id":"w17967415","type":"way","role":""},{"id":"w41074899","type":"way","role":""},{"id":"w17967581","type":"way","role":""},{"id":"w41074902","type":"way","role":""},{"id":"w41074906","type":"way","role":""},{"id":"w209707997","type":"way","role":""},{"id":"w209707998","type":"way","role":""},{"id":"w17964798","type":"way","role":""},{"id":"w17966034","type":"way","role":""},{"id":"w17967593","type":"way","role":""},{"id":"w41074888","type":"way","role":""},{"id":"w17733772","type":"way","role":""},{"id":"w41074813","type":"way","role":""},{"id":"w17742213","type":"way","role":""},{"id":"w17746863","type":"way","role":""},{"id":"w17745772","type":"way","role":""},{"id":"w17742222","type":"way","role":""},{"id":"w17745922","type":"way","role":""},{"id":"w17742198","type":"way","role":""},{"id":"w17747675","type":"way","role":""},{"id":"w17739927","type":"way","role":""},{"id":"w17745708","type":"way","role":""},{"id":"w41006323","type":"way","role":""},{"id":"w17744233","type":"way","role":""},{"id":"w17739436","type":"way","role":""},{"id":"w17742201","type":"way","role":""},{"id":"w151418616","type":"way","role":""},{"id":"w17750062","type":"way","role":""},{"id":"w17742227","type":"way","role":"east"},{"id":"w41006348","type":"way","role":"east"},{"id":"w41260984","type":"way","role":""},{"id":"w17832427","type":"way","role":""},{"id":"w17838408","type":"way","role":""},{"id":"w17835846","type":"way","role":""},{"id":"w17832923","type":"way","role":""},{"id":"w17839388","type":"way","role":""},{"id":"w17838390","type":"way","role":""},{"id":"w17831272","type":"way","role":""},{"id":"w17828581","type":"way","role":""},{"id":"w38240686","type":"way","role":""},{"id":"w17838405","type":"way","role":"east"},{"id":"w123323711","type":"way","role":"east"},{"id":"w17830167","type":"way","role":"east"},{"id":"w99011909","type":"way","role":"east"},{"id":"w41911361","type":"way","role":"east"},{"id":"w41911355","type":"way","role":"east"},{"id":"w41911356","type":"way","role":"east"},{"id":"w117148326","type":"way","role":"west"},{"id":"w41911352","type":"way","role":"west"},{"id":"w41911353","type":"way","role":"west"},{"id":"w41911354","type":"way","role":"west"},{"id":"w41911360","type":"way","role":"west"},{"id":"w38240676","type":"way","role":"west"},{"id":"w123323710","type":"way","role":"west"},{"id":"w41260271","type":"way","role":"east"},{"id":"w41260273","type":"way","role":"east"},{"id":"w17964031","type":"way","role":"east"},{"id":"w41006344","type":"way","role":"west"},{"id":"w41006351","type":"way","role":"west"}]},"n367813436":{"id":"n367813436","loc":[-85.63605205663384,41.94305506683346],"tags":{"amenity":"fire_station","name":"Three Rivers Fire Department"}},"n185948708":{"id":"n185948708","loc":[-85.6369828,41.9408789]},"n185948710":{"id":"n185948710","loc":[-85.6370184,41.9411346]},"n185954691":{"id":"n185954691","loc":[-85.634476,41.941475]},"n185954692":{"id":"n185954692","loc":[-85.635008,41.941846]},"n185954693":{"id":"n185954693","loc":[-85.635362,41.941962]},"n185954695":{"id":"n185954695","loc":[-85.63578,41.941978]},"n185972903":{"id":"n185972903","loc":[-85.63295,41.9430062]},"n185964971":{"id":"n185964971","loc":[-85.6346811,41.9431023]},"n1819805854":{"id":"n1819805854","loc":[-85.6331275,41.9404837]},"n1819805918":{"id":"n1819805918","loc":[-85.6331168,41.942798]},"n1819805762":{"id":"n1819805762","loc":[-85.6333034,41.9424123]},"n1819805907":{"id":"n1819805907","loc":[-85.6334819,41.9419121]},"n1819805915":{"id":"n1819805915","loc":[-85.6334554,41.9413588]},"n1819848888":{"id":"n1819848888","loc":[-85.6331625,41.942679]},"n1819848930":{"id":"n1819848930","loc":[-85.6338684,41.9431252]},"n1819858505":{"id":"n1819858505","loc":[-85.6346782,41.9429092]},"n1819858507":{"id":"n1819858507","loc":[-85.6339003,41.9414534]},"n1819858508":{"id":"n1819858508","loc":[-85.6345709,41.9427742]},"n1819858509":{"id":"n1819858509","loc":[-85.63419,41.9417322]},"n1819858511":{"id":"n1819858511","loc":[-85.6340666,41.9415652]},"n1819858512":{"id":"n1819858512","loc":[-85.6343295,41.9423027]},"n1819858514":{"id":"n1819858514","loc":[-85.6343241,41.942207]},"n1819858521":{"id":"n1819858521","loc":[-85.633391,41.941231]},"n1819858528":{"id":"n1819858528","loc":[-85.6343027,41.9419716]},"n185954683":{"id":"n185954683","loc":[-85.6335412,41.940147]},"n185954685":{"id":"n185954685","loc":[-85.6334296,41.9403023]},"n185954687":{"id":"n185954687","loc":[-85.6333988,41.9404704]},"n185954689":{"id":"n185954689","loc":[-85.6335511,41.9410225]},"n185954690":{"id":"n185954690","loc":[-85.6336721,41.9411669]},"n1820938802":{"id":"n1820938802","loc":[-85.6330671,41.941845]},"n1821006702":{"id":"n1821006702","loc":[-85.6344047,41.9395496]},"n2130304133":{"id":"n2130304133","loc":[-85.6349025,41.9427659]},"n2130304136":{"id":"n2130304136","loc":[-85.6346027,41.9422017]},"n2130304138":{"id":"n2130304138","loc":[-85.6348577,41.9421517]},"n2130304140":{"id":"n2130304140","loc":[-85.6348419,41.9422694]},"n2130304142":{"id":"n2130304142","loc":[-85.6349071,41.9423135]},"n2130304144":{"id":"n2130304144","loc":[-85.6350495,41.9423312]},"n2130304146":{"id":"n2130304146","loc":[-85.6351009,41.9422812]},"n2130304147":{"id":"n2130304147","loc":[-85.6351227,41.9421532]},"n2130304148":{"id":"n2130304148","loc":[-85.635526,41.9421547]},"n2130304149":{"id":"n2130304149","loc":[-85.6355339,41.9425768]},"n2130304150":{"id":"n2130304150","loc":[-85.6351582,41.9426562]},"n2130304151":{"id":"n2130304151","loc":[-85.6351207,41.9427032]},"n2138493807":{"id":"n2138493807","loc":[-85.6350923,41.9415216]},"n2138493808":{"id":"n2138493808","loc":[-85.6353603,41.9411061]},"n2138493809":{"id":"n2138493809","loc":[-85.6354421,41.9410942]},"n2138493810":{"id":"n2138493810","loc":[-85.6355079,41.9411044]},"n2138493811":{"id":"n2138493811","loc":[-85.6355693,41.9411246]},"n2138493812":{"id":"n2138493812","loc":[-85.6355829,41.9411061]},"n2138493813":{"id":"n2138493813","loc":[-85.6355624,41.9409777]},"n2138493814":{"id":"n2138493814","loc":[-85.6355011,41.9409152]},"n2138493815":{"id":"n2138493815","loc":[-85.635383,41.9409219]},"n2138493816":{"id":"n2138493816","loc":[-85.635299,41.9409658]},"n2138493817":{"id":"n2138493817","loc":[-85.6351695,41.941204]},"n2138493818":{"id":"n2138493818","loc":[-85.6348879,41.9415166]},"n2138493819":{"id":"n2138493819","loc":[-85.634897,41.9415757]},"n2138493820":{"id":"n2138493820","loc":[-85.6349606,41.9416399]},"n2138493821":{"id":"n2138493821","loc":[-85.6350219,41.9416669]},"n2138493822":{"id":"n2138493822","loc":[-85.6351241,41.9416314]},"n2138493823":{"id":"n2138493823","loc":[-85.6350855,41.9415622]},"n2138493824":{"id":"n2138493824","loc":[-85.6350401,41.9413603]},"n2138493825":{"id":"n2138493825","loc":[-85.6352206,41.9410765]},"n2138493826":{"id":"n2138493826","loc":[-85.6343865,41.9415594]},"n2138493827":{"id":"n2138493827","loc":[-85.6343506,41.9415873]},"n2138493828":{"id":"n2138493828","loc":[-85.6344158,41.9417557]},"n2138493829":{"id":"n2138493829","loc":[-85.6344614,41.9417968]},"n2138493830":{"id":"n2138493830","loc":[-85.6345005,41.9418186]},"n2138493831":{"id":"n2138493831","loc":[-85.6345965,41.9418162]},"n2138493832":{"id":"n2138493832","loc":[-85.6347317,41.9417242]},"n2138493833":{"id":"n2138493833","loc":[-85.6346722,41.941775]},"n2139858909":{"id":"n2139858909","loc":[-85.633403,41.9391006]},"n2139858910":{"id":"n2139858910","loc":[-85.6332973,41.9393967]},"n2139858911":{"id":"n2139858911","loc":[-85.633205,41.9396742]},"n2139858912":{"id":"n2139858912","loc":[-85.6332203,41.9397772]},"n2139858913":{"id":"n2139858913","loc":[-85.6333453,41.939936]},"n2139858914":{"id":"n2139858914","loc":[-85.6333761,41.9400018]},"n2139858915":{"id":"n2139858915","loc":[-85.63328,41.9402249]},"n2139858916":{"id":"n2139858916","loc":[-85.6332357,41.9403523]},"n2139858917":{"id":"n2139858917","loc":[-85.6332838,41.9405831]},"n2139858918":{"id":"n2139858918","loc":[-85.6333643,41.9408744]},"n2139858919":{"id":"n2139858919","loc":[-85.6334394,41.9410519]},"n2139858920":{"id":"n2139858920","loc":[-85.6335815,41.9411717]},"n2139858921":{"id":"n2139858921","loc":[-85.6337478,41.9412734]},"n2139858922":{"id":"n2139858922","loc":[-85.6343174,41.9415268]},"n2139858923":{"id":"n2139858923","loc":[-85.6343886,41.9417397]},"n2139858924":{"id":"n2139858924","loc":[-85.6344407,41.9418015]},"n2139858925":{"id":"n2139858925","loc":[-85.6345139,41.9418366]},"n2139858926":{"id":"n2139858926","loc":[-85.6344846,41.942005]},"n2139858927":{"id":"n2139858927","loc":[-85.6345775,41.9422218]},"n2139858928":{"id":"n2139858928","loc":[-85.6348771,41.9427814]},"n2139858929":{"id":"n2139858929","loc":[-85.6349487,41.9427995]},"n2139858930":{"id":"n2139858930","loc":[-85.6350415,41.9427874]},"n2139858931":{"id":"n2139858931","loc":[-85.6351246,41.9428589]},"n2139858978":{"id":"n2139858978","loc":[-85.6349658,41.9431481]},"n2139858979":{"id":"n2139858979","loc":[-85.6350081,41.9431287]},"n2139858980":{"id":"n2139858980","loc":[-85.6349967,41.9430997]},"n2139858981":{"id":"n2139858981","loc":[-85.6352158,41.9430352]},"n2139858982":{"id":"n2139858982","loc":[-85.6348174,41.94267]},"n2139858983":{"id":"n2139858983","loc":[-85.6346142,41.9425989]},"n2139858984":{"id":"n2139858984","loc":[-85.6344938,41.9423809]},"n2139858985":{"id":"n2139858985","loc":[-85.6344856,41.9422997]},"n2139870380":{"id":"n2139870380","loc":[-85.6346707,41.9417955]},"n2139870381":{"id":"n2139870381","loc":[-85.6345949,41.9418311]},"n2139870382":{"id":"n2139870382","loc":[-85.6343322,41.9418659]},"n2139870383":{"id":"n2139870383","loc":[-85.6342072,41.941885]},"n2139870384":{"id":"n2139870384","loc":[-85.6341325,41.9418919]},"n2139870385":{"id":"n2139870385","loc":[-85.6341314,41.9422028]},"n2139870386":{"id":"n2139870386","loc":[-85.6340472,41.9423271]},"n2139870387":{"id":"n2139870387","loc":[-85.6342185,41.9427933]},"n2139870388":{"id":"n2139870388","loc":[-85.6340605,41.9423924]},"n2139870389":{"id":"n2139870389","loc":[-85.6339889,41.9424069]},"n2139870390":{"id":"n2139870390","loc":[-85.633971,41.942356]},"n2139870391":{"id":"n2139870391","loc":[-85.63361,41.9424235]},"n2139870392":{"id":"n2139870392","loc":[-85.6337137,41.9426819]},"n2139870393":{"id":"n2139870393","loc":[-85.6336977,41.9428632]},"n2139870394":{"id":"n2139870394","loc":[-85.6338823,41.9428647]},"n2139870395":{"id":"n2139870395","loc":[-85.6339412,41.9430069]},"n2139870396":{"id":"n2139870396","loc":[-85.6338873,41.9430353]},"n2139870397":{"id":"n2139870397","loc":[-85.6337676,41.942815]},"n2139870398":{"id":"n2139870398","loc":[-85.6336822,41.9423505]},"n2139870399":{"id":"n2139870399","loc":[-85.634037,41.9422725]},"n2139870400":{"id":"n2139870400","loc":[-85.6340294,41.9422518]},"n2139870401":{"id":"n2139870401","loc":[-85.6336726,41.9423312]},"n2139870402":{"id":"n2139870402","loc":[-85.6342188,41.9425715]},"n2139870403":{"id":"n2139870403","loc":[-85.6342524,41.942565]},"n2139870404":{"id":"n2139870404","loc":[-85.6341438,41.942299]},"n2139870405":{"id":"n2139870405","loc":[-85.6341149,41.9423061]},"n2139870407":{"id":"n2139870407","loc":[-85.6340846,41.9431458]},"n2139870408":{"id":"n2139870408","loc":[-85.6339436,41.9429032]},"n2139870409":{"id":"n2139870409","loc":[-85.6343143,41.9428207]},"n2139870410":{"id":"n2139870410","loc":[-85.6343507,41.94277]},"n2139870411":{"id":"n2139870411","loc":[-85.6341527,41.942254]},"n2139870412":{"id":"n2139870412","loc":[-85.6340925,41.9422199]},"n2139870413":{"id":"n2139870413","loc":[-85.6335435,41.9423433]},"n2139870414":{"id":"n2139870414","loc":[-85.6335023,41.9423975]},"n2139870415":{"id":"n2139870415","loc":[-85.6335086,41.9424552]},"n2139870416":{"id":"n2139870416","loc":[-85.6336296,41.942665]},"n2139870417":{"id":"n2139870417","loc":[-85.6341396,41.9428596]},"n2139870418":{"id":"n2139870418","loc":[-85.6339701,41.9424487]},"n2139870419":{"id":"n2139870419","loc":[-85.6335514,41.9425294]},"n2139870420":{"id":"n2139870420","loc":[-85.6337406,41.9424929]},"n2139870421":{"id":"n2139870421","loc":[-85.6338939,41.9428687]},"n2139870422":{"id":"n2139870422","loc":[-85.6341323,41.9419538]},"n2139870423":{"id":"n2139870423","loc":[-85.6340321,41.9420376]},"n2139870424":{"id":"n2139870424","loc":[-85.6337648,41.942238]},"n2139870425":{"id":"n2139870425","loc":[-85.6337604,41.9422685]},"n2139870426":{"id":"n2139870426","loc":[-85.6337682,41.9422928]},"n2139870427":{"id":"n2139870427","loc":[-85.6338086,41.9423862]},"n2139870428":{"id":"n2139870428","loc":[-85.6349465,41.9416631]},"n2139870429":{"id":"n2139870429","loc":[-85.6351097,41.9416973]},"n2139870430":{"id":"n2139870430","loc":[-85.6353371,41.9416798]},"n2139870431":{"id":"n2139870431","loc":[-85.6349627,41.9422506]},"n2139870432":{"id":"n2139870432","loc":[-85.634979,41.9421815]},"n2139870433":{"id":"n2139870433","loc":[-85.634885,41.9421679]},"n2139870434":{"id":"n2139870434","loc":[-85.6348689,41.9422377]},"n2139870435":{"id":"n2139870435","loc":[-85.6349779,41.9419486]},"n2139870436":{"id":"n2139870436","loc":[-85.6349505,41.9418933]},"n2139870437":{"id":"n2139870437","loc":[-85.6347327,41.9419505]},"n2139870438":{"id":"n2139870438","loc":[-85.6347614,41.9420087]},"n2139870439":{"id":"n2139870439","loc":[-85.6351889,41.9416912]},"n2139870440":{"id":"n2139870440","loc":[-85.6351092,41.9418426]},"n2139870441":{"id":"n2139870441","loc":[-85.635086,41.9419659]},"n2139870442":{"id":"n2139870442","loc":[-85.6350584,41.9421466]},"n2139870443":{"id":"n2139870443","loc":[-85.6350993,41.9421606]},"n2139870444":{"id":"n2139870444","loc":[-85.6350993,41.9422132]},"n2139870445":{"id":"n2139870445","loc":[-85.6350794,41.9422855]},"n2139870446":{"id":"n2139870446","loc":[-85.6350474,41.9423159]},"n2139870447":{"id":"n2139870447","loc":[-85.6349251,41.9422998]},"n2139870448":{"id":"n2139870448","loc":[-85.634911,41.9422755]},"n2139870449":{"id":"n2139870449","loc":[-85.6349157,41.9422553]},"n2139870450":{"id":"n2139870450","loc":[-85.6347213,41.9419324]},"n2139870451":{"id":"n2139870451","loc":[-85.6349535,41.9418771]},"n2139870452":{"id":"n2139870452","loc":[-85.6350135,41.9419421]},"n2139870453":{"id":"n2139870453","loc":[-85.6348584,41.9418997]},"n2139870454":{"id":"n2139870454","loc":[-85.6348113,41.9418101]},"n2139870455":{"id":"n2139870455","loc":[-85.6347306,41.9417449]},"n2139870456":{"id":"n2139870456","loc":[-85.6349123,41.941776]},"n2139870457":{"id":"n2139870457","loc":[-85.6349423,41.9421448]},"n2139870458":{"id":"n2139870458","loc":[-85.6349436,41.9420652]},"n2139870459":{"id":"n2139870459","loc":[-85.6349136,41.9419963]},"n2139870460":{"id":"n2139870460","loc":[-85.6349814,41.9419789]},"n2139989328":{"id":"n2139989328","loc":[-85.6334188,41.9421725]},"n2139989330":{"id":"n2139989330","loc":[-85.6335087,41.9416308]},"n2139989335":{"id":"n2139989335","loc":[-85.6336856,41.9429371]},"n2139989337":{"id":"n2139989337","loc":[-85.6333713,41.9427217]},"n2139989339":{"id":"n2139989339","loc":[-85.6332912,41.9425383]},"n2139989341":{"id":"n2139989341","loc":[-85.6339369,41.9409198]},"n2139989344":{"id":"n2139989344","loc":[-85.634097,41.9409469]},"n2139989346":{"id":"n2139989346","loc":[-85.634137,41.9412852]},"n2139989348":{"id":"n2139989348","loc":[-85.6344536,41.9414151]},"n2139989350":{"id":"n2139989350","loc":[-85.6350794,41.9412392]},"n2139989351":{"id":"n2139989351","loc":[-85.6352541,41.9409387]},"n2139989353":{"id":"n2139989353","loc":[-85.6357198,41.9408007]},"n2139989355":{"id":"n2139989355","loc":[-85.6357235,41.9427088]},"n2139989357":{"id":"n2139989357","loc":[-85.6337119,41.9421256]},"n2139989359":{"id":"n2139989359","loc":[-85.6336913,41.9420655]},"n2139989360":{"id":"n2139989360","loc":[-85.633582,41.9420867]},"n2139989362":{"id":"n2139989362","loc":[-85.6336058,41.9421491]},"n2139989364":{"id":"n2139989364","loc":[-85.6339685,41.9410995]},"n2139989366":{"id":"n2139989366","loc":[-85.6339067,41.9411383]},"n2139989368":{"id":"n2139989368","loc":[-85.6339685,41.9411972]},"n2139989370":{"id":"n2139989370","loc":[-85.6340398,41.9411619]},"n2139870379":{"id":"n2139870379","loc":[-85.6348391,41.9416651]},"n2140006363":{"id":"n2140006363","loc":[-85.6353144,41.9430345]},"n2140006364":{"id":"n2140006364","loc":[-85.6349191,41.9431422]},"n2140018997":{"id":"n2140018997","loc":[-85.63645945147184,41.942986488012565],"tags":{"amenity":"townhall","name":"Three Rivers City Hall"}},"n2140018998":{"id":"n2140018998","loc":[-85.6370319,41.9427919]},"n2140018999":{"id":"n2140018999","loc":[-85.6360687,41.9427808]},"n2199856288":{"id":"n2199856288","loc":[-85.6344968,41.9407307]},"n2199856289":{"id":"n2199856289","loc":[-85.634492,41.9406036]},"n2199856290":{"id":"n2199856290","loc":[-85.634891,41.9406001]},"n2199856291":{"id":"n2199856291","loc":[-85.6348894,41.9405288]},"n2199856292":{"id":"n2199856292","loc":[-85.6349166,41.94053]},"n2199856293":{"id":"n2199856293","loc":[-85.6349166,41.9404956]},"n2199856294":{"id":"n2199856294","loc":[-85.6350219,41.9404956]},"n2199856295":{"id":"n2199856295","loc":[-85.6350251,41.94053]},"n2199856296":{"id":"n2199856296","loc":[-85.6350538,41.9405288]},"n2199856297":{"id":"n2199856297","loc":[-85.6350602,41.94079]},"n2199856298":{"id":"n2199856298","loc":[-85.6351703,41.9407912]},"n2199856299":{"id":"n2199856299","loc":[-85.6351688,41.9409171]},"n2199856300":{"id":"n2199856300","loc":[-85.6347889,41.9409135]},"n2199856301":{"id":"n2199856301","loc":[-85.6347921,41.94079]},"n2199856302":{"id":"n2199856302","loc":[-85.6348942,41.9407888]},"n2199856303":{"id":"n2199856303","loc":[-85.6348926,41.9407283]},"n185951869":{"id":"n185951869","loc":[-85.6387639,41.957288]},"n185958643":{"id":"n185958643","loc":[-85.636746,41.929221]},"n185958645":{"id":"n185958645","loc":[-85.636791,41.929363]},"n185958647":{"id":"n185958647","loc":[-85.6375975,41.9314987]},"n185958649":{"id":"n185958649","loc":[-85.637669,41.931667]},"n185958651":{"id":"n185958651","loc":[-85.637728,41.931901]},"n185958653":{"id":"n185958653","loc":[-85.637724,41.932187]},"n185958656":{"id":"n185958656","loc":[-85.637732,41.932761]},"n185958658":{"id":"n185958658","loc":[-85.637688,41.93398]},"n185958660":{"id":"n185958660","loc":[-85.637685,41.934223]},"n185958662":{"id":"n185958662","loc":[-85.6376468,41.9350232]},"n185958664":{"id":"n185958664","loc":[-85.637564,41.937028]},"n185958666":{"id":"n185958666","loc":[-85.637458,41.938197]},"n185958668":{"id":"n185958668","loc":[-85.637424,41.938692]},"n185964972":{"id":"n185964972","loc":[-85.6341901,41.9432732]},"n185971361":{"id":"n185971361","loc":[-85.635762,41.938208]},"n185971364":{"id":"n185971364","loc":[-85.635732,41.9384]},"n185971366":{"id":"n185971366","loc":[-85.635736,41.938697]},"n185972775":{"id":"n185972775","loc":[-85.635638,42.070357]},"n185972777":{"id":"n185972777","loc":[-85.635724,42.069929]},"n185972779":{"id":"n185972779","loc":[-85.635804,42.069248]},"n185972781":{"id":"n185972781","loc":[-85.635869,42.068361]},"n185972783":{"id":"n185972783","loc":[-85.635883,42.067582]},"n185972785":{"id":"n185972785","loc":[-85.635875,42.067114]},"n185972787":{"id":"n185972787","loc":[-85.635778,42.065359]},"n185972788":{"id":"n185972788","loc":[-85.635728,42.063416]},"n185972789":{"id":"n185972789","loc":[-85.635665,42.062491]},"n185972790":{"id":"n185972790","loc":[-85.635617,42.061928]},"n185972791":{"id":"n185972791","loc":[-85.635614,42.061898]},"n185972793":{"id":"n185972793","loc":[-85.635379,42.060288]},"n185972795":{"id":"n185972795","loc":[-85.635092,42.05799]},"n185972797":{"id":"n185972797","loc":[-85.634843,42.055781]},"n185972798":{"id":"n185972798","loc":[-85.634817,42.055549]},"n185972800":{"id":"n185972800","loc":[-85.634708,42.053942]},"n185972802":{"id":"n185972802","loc":[-85.634447,42.051809]},"n185972805":{"id":"n185972805","loc":[-85.634241,42.04946]},"n185972807":{"id":"n185972807","loc":[-85.633787,42.045926]},"n185972809":{"id":"n185972809","loc":[-85.633811,42.045645]},"n185972811":{"id":"n185972811","loc":[-85.63373,42.043626]},"n185972813":{"id":"n185972813","loc":[-85.633698,42.042184]},"n185972814":{"id":"n185972814","loc":[-85.63369,42.04181]},"n185972815":{"id":"n185972815","loc":[-85.633681,42.040714]},"n185972816":{"id":"n185972816","loc":[-85.633571,42.036322]},"n185972817":{"id":"n185972817","loc":[-85.633537,42.034044]},"n185972819":{"id":"n185972819","loc":[-85.633481,42.030785]},"n185972821":{"id":"n185972821","loc":[-85.633452,42.027538]},"n185972824":{"id":"n185972824","loc":[-85.633438,42.027427]},"n185972826":{"id":"n185972826","loc":[-85.633342,42.022656]},"n185972830":{"id":"n185972830","loc":[-85.63327,42.020724]},"n185972832":{"id":"n185972832","loc":[-85.633198,42.019106]},"n185972834":{"id":"n185972834","loc":[-85.633249,42.018363]},"n185972835":{"id":"n185972835","loc":[-85.633139,42.012944]},"n185972836":{"id":"n185972836","loc":[-85.63309,42.008284]},"n185972839":{"id":"n185972839","loc":[-85.63298,42.00005]},"n185972845":{"id":"n185972845","loc":[-85.6325369,41.9764959]},"n185972847":{"id":"n185972847","loc":[-85.6327549,41.9750005]},"n185972849":{"id":"n185972849","loc":[-85.6329374,41.9742527]},"n185972851":{"id":"n185972851","loc":[-85.6331387,41.9736039]},"n185972862":{"id":"n185972862","loc":[-85.6383589,41.9585023]},"n185972868":{"id":"n185972868","loc":[-85.6393633,41.9551716]},"n185972878":{"id":"n185972878","loc":[-85.639377,41.95335]},"n185972882":{"id":"n185972882","loc":[-85.6389179,41.9516944]},"n185972885":{"id":"n185972885","loc":[-85.6387444,41.9512105]},"n185972891":{"id":"n185972891","loc":[-85.636421,41.946392]},"n185972895":{"id":"n185972895","loc":[-85.635965,41.945809]},"n185972897":{"id":"n185972897","loc":[-85.635683,41.945449]},"n185972899":{"id":"n185972899","loc":[-85.635281,41.9450252]},"n185972905":{"id":"n185972905","loc":[-85.6324428,41.9425743]},"n185985217":{"id":"n185985217","loc":[-85.638243,41.943674]},"n185985219":{"id":"n185985219","loc":[-85.638228,41.943747]},"n185985221":{"id":"n185985221","loc":[-85.638163,41.943797]},"n185985222":{"id":"n185985222","loc":[-85.638089,41.943832]},"n185985223":{"id":"n185985223","loc":[-85.637969,41.943841]},"n185985225":{"id":"n185985225","loc":[-85.637841,41.943833]},"n185985227":{"id":"n185985227","loc":[-85.637601,41.943789]},"n185985229":{"id":"n185985229","loc":[-85.637449,41.943754]},"n185985231":{"id":"n185985231","loc":[-85.637342,41.943734]},"n185985233":{"id":"n185985233","loc":[-85.637218,41.943703]},"n185985235":{"id":"n185985235","loc":[-85.637151,41.943663]},"n185985238":{"id":"n185985238","loc":[-85.637118,41.943615]},"n185985240":{"id":"n185985240","loc":[-85.637073,41.943494]},"n185990434":{"id":"n185990434","loc":[-85.6329028,41.9984292],"tags":{"railway":"level_crossing"}},"n1475284023":{"id":"n1475284023","loc":[-85.6336163,41.9435806],"tags":{"railway":"level_crossing"}},"n1475293222":{"id":"n1475293222","loc":[-85.6394045,41.953658],"tags":{"railway":"level_crossing"}},"n1475293226":{"id":"n1475293226","loc":[-85.6364975,41.9638663],"tags":{"railway":"level_crossing"}},"n1475293234":{"id":"n1475293234","loc":[-85.6390449,41.9565145]},"n1475293240":{"id":"n1475293240","loc":[-85.636943,41.9473114]},"n1475293252":{"id":"n1475293252","loc":[-85.6392115,41.9559003]},"n1475293254":{"id":"n1475293254","loc":[-85.6348931,41.9685127],"tags":{"railway":"level_crossing"}},"n1475293260":{"id":"n1475293260","loc":[-85.6375999,41.9485401]},"n1475293261":{"id":"n1475293261","loc":[-85.6391256,41.9523817],"tags":{"railway":"level_crossing"}},"n1475293264":{"id":"n1475293264","loc":[-85.6394155,41.9546493],"tags":{"railway":"level_crossing"}},"n1819805614":{"id":"n1819805614","loc":[-85.6345652,41.9363097]},"n1819805618":{"id":"n1819805618","loc":[-85.6295334,41.9426862]},"n1819805622":{"id":"n1819805622","loc":[-85.6308208,41.9430773]},"n1819805626":{"id":"n1819805626","loc":[-85.6274734,41.9406592]},"n1819805629":{"id":"n1819805629","loc":[-85.6296943,41.9430533]},"n1819805632":{"id":"n1819805632","loc":[-85.6340931,41.9354477]},"n1819805636":{"id":"n1819805636","loc":[-85.6304131,41.9436598]},"n1819805639":{"id":"n1819805639","loc":[-85.6304882,41.9426623]},"n1819805641":{"id":"n1819805641","loc":[-85.6336103,41.9367487]},"n1819805643":{"id":"n1819805643","loc":[-85.6300376,41.9418084]},"n1819805645":{"id":"n1819805645","loc":[-85.6365286,41.9336679]},"n1819805647":{"id":"n1819805647","loc":[-85.632016,41.9429221]},"n1819805666":{"id":"n1819805666","loc":[-85.6314753,41.9442663]},"n1819805669":{"id":"n1819805669","loc":[-85.6268619,41.9402203]},"n1819805673":{"id":"n1819805673","loc":[-85.6296728,41.9412099]},"n1819805676":{"id":"n1819805676","loc":[-85.6354557,41.932766]},"n1819805680":{"id":"n1819805680","loc":[-85.632752,41.9431012]},"n1819805683":{"id":"n1819805683","loc":[-85.631147,41.9432014]},"n1819805687":{"id":"n1819805687","loc":[-85.635284,41.9343942]},"n1819805690":{"id":"n1819805690","loc":[-85.6249736,41.9405794]},"n1819805694":{"id":"n1819805694","loc":[-85.6294153,41.9417925]},"n1819805698":{"id":"n1819805698","loc":[-85.6323486,41.9426986]},"n1819805702":{"id":"n1819805702","loc":[-85.6340287,41.9373871]},"n1819805707":{"id":"n1819805707","loc":[-85.6353698,41.9316326]},"n1819805711":{"id":"n1819805711","loc":[-85.6284176,41.940356]},"n1819805715":{"id":"n1819805715","loc":[-85.6291471,41.9412897]},"n1819805718":{"id":"n1819805718","loc":[-85.6311105,41.943979]},"n1819805722":{"id":"n1819805722","loc":[-85.6320868,41.9400128]},"n1819805724":{"id":"n1819805724","loc":[-85.635166,41.9324627]},"n1819805727":{"id":"n1819805727","loc":[-85.6344686,41.9350567]},"n1819805728":{"id":"n1819805728","loc":[-85.6357132,41.9332369]},"n1819805731":{"id":"n1819805731","loc":[-85.629984,41.9434444]},"n1819805760":{"id":"n1819805760","loc":[-85.6330996,41.9378784]},"n1819805766":{"id":"n1819805766","loc":[-85.625274,41.9411141]},"n1819805770":{"id":"n1819805770","loc":[-85.6326321,41.9412173]},"n1819805774":{"id":"n1819805774","loc":[-85.6347047,41.9312096]},"n1819805777":{"id":"n1819805777","loc":[-85.6363569,41.9339552]},"n1819805780":{"id":"n1819805780","loc":[-85.6327392,41.941926]},"n1819805783":{"id":"n1819805783","loc":[-85.6357239,41.9338435]},"n1819805786":{"id":"n1819805786","loc":[-85.6356595,41.9346576]},"n1819805789":{"id":"n1819805789","loc":[-85.6316469,41.9436598]},"n1819805792":{"id":"n1819805792","loc":[-85.6350587,41.9354557]},"n1819805795":{"id":"n1819805795","loc":[-85.6360028,41.9322791]},"n1819805798":{"id":"n1819805798","loc":[-85.63125,41.9443062]},"n1819805802":{"id":"n1819805802","loc":[-85.6263362,41.9408109]},"n1819805805":{"id":"n1819805805","loc":[-85.6315075,41.9438753]},"n1819805808":{"id":"n1819805808","loc":[-85.6340008,41.9316051]},"n1819805810":{"id":"n1819805810","loc":[-85.6345545,41.9320557]},"n1819805812":{"id":"n1819805812","loc":[-85.6250809,41.9408587]},"n1819805814":{"id":"n1819805814","loc":[-85.6257783,41.9400926]},"n1819805834":{"id":"n1819805834","loc":[-85.6326408,41.9424363]},"n1819805838":{"id":"n1819805838","loc":[-85.6365607,41.9334365]},"n1819805842":{"id":"n1819805842","loc":[-85.6288253,41.9410343]},"n1819805846":{"id":"n1819805846","loc":[-85.6279133,41.9402921]},"n1819805849":{"id":"n1819805849","loc":[-85.6289433,41.9405156]},"n1819805852":{"id":"n1819805852","loc":[-85.6313787,41.9439152]},"n1819805858":{"id":"n1819805858","loc":[-85.6300805,41.9420398]},"n1819805861":{"id":"n1819805861","loc":[-85.6321941,41.9396297]},"n1819805864":{"id":"n1819805864","loc":[-85.6329129,41.9393903]},"n1819805868":{"id":"n1819805868","loc":[-85.632001,41.9434922]},"n1819805870":{"id":"n1819805870","loc":[-85.6314903,41.9431535]},"n1819805873":{"id":"n1819805873","loc":[-85.6251667,41.9401166]},"n1819805876":{"id":"n1819805876","loc":[-85.63287,41.939941]},"n1819805878":{"id":"n1819805878","loc":[-85.6307886,41.9437317]},"n1819805880":{"id":"n1819805880","loc":[-85.6321727,41.940348]},"n1819805883":{"id":"n1819805883","loc":[-85.6265872,41.940113]},"n1819805885":{"id":"n1819805885","loc":[-85.6268404,41.9406672]},"n1819805887":{"id":"n1819805887","loc":[-85.6325267,41.9389035]},"n1819805889":{"id":"n1819805889","loc":[-85.6364964,41.933189]},"n1819805911":{"id":"n1819805911","loc":[-85.6248663,41.9401804]},"n1819805922":{"id":"n1819805922","loc":[-85.633267,41.9387199]},"n1819805925":{"id":"n1819805925","loc":[-85.6293402,41.9408428]},"n1819848849":{"id":"n1819848849","loc":[-85.6464957,41.9695178]},"n1819848850":{"id":"n1819848850","loc":[-85.6497642,41.9611355]},"n1819848851":{"id":"n1819848851","loc":[-85.6480943,41.9624818]},"n1819848854":{"id":"n1819848854","loc":[-85.6500362,41.9657367]},"n1819848855":{"id":"n1819848855","loc":[-85.6493673,41.9783496]},"n1819848856":{"id":"n1819848856","loc":[-85.6457409,41.9548007]},"n1819848857":{"id":"n1819848857","loc":[-85.651313,41.9760426]},"n1819848858":{"id":"n1819848858","loc":[-85.6495819,41.9784772]},"n1819848859":{"id":"n1819848859","loc":[-85.6495105,41.9833722]},"n1819848860":{"id":"n1819848860","loc":[-85.6405053,41.9492792]},"n1819848863":{"id":"n1819848863","loc":[-85.6502293,41.9786826]},"n1819848865":{"id":"n1819848865","loc":[-85.6406877,41.9495106]},"n1819848870":{"id":"n1819848870","loc":[-85.6493136,41.9704611]},"n1819848871":{"id":"n1819848871","loc":[-85.6372249,41.9441284]},"n1819848873":{"id":"n1819848873","loc":[-85.6512379,41.9659441]},"n1819848875":{"id":"n1819848875","loc":[-85.6508087,41.9650187]},"n1819848877":{"id":"n1819848877","loc":[-85.6487166,41.9605352]},"n1819848878":{"id":"n1819848878","loc":[-85.6506478,41.9760665]},"n1819848879":{"id":"n1819848879","loc":[-85.651431,41.9758512]},"n1819848886":{"id":"n1819848886","loc":[-85.6477617,41.9563945]},"n1819848889":{"id":"n1819848889","loc":[-85.6497895,41.9832286]},"n1819848892":{"id":"n1819848892","loc":[-85.6504868,41.9791931]},"n1819848893":{"id":"n1819848893","loc":[-85.6498002,41.9615085]},"n1819848894":{"id":"n1819848894","loc":[-85.6404302,41.9502846]},"n1819848901":{"id":"n1819848901","loc":[-85.6354412,41.9439886]},"n1819848903":{"id":"n1819848903","loc":[-85.6472145,41.9698528]},"n1819848904":{"id":"n1819848904","loc":[-85.6401979,41.9486233]},"n1819848905":{"id":"n1819848905","loc":[-85.6475042,41.963503]},"n1819848909":{"id":"n1819848909","loc":[-85.6343405,41.94358]},"n1819848914":{"id":"n1819848914","loc":[-85.6503474,41.9737773]},"n1819848915":{"id":"n1819848915","loc":[-85.6389533,41.9470992]},"n1819848916":{"id":"n1819848916","loc":[-85.6483625,41.9577907]},"n1819848917":{"id":"n1819848917","loc":[-85.6484768,41.9617419]},"n1819848918":{"id":"n1819848918","loc":[-85.644078,41.9545693]},"n1819848919":{"id":"n1819848919","loc":[-85.6437169,41.9543041]},"n1819848920":{"id":"n1819848920","loc":[-85.6478331,41.9627949]},"n1819848922":{"id":"n1819848922","loc":[-85.6499144,41.9785889]},"n1819848924":{"id":"n1819848924","loc":[-85.647633,41.9720066]},"n1819848926":{"id":"n1819848926","loc":[-85.6487987,41.978868]},"n1819848927":{"id":"n1819848927","loc":[-85.6495105,41.9730355]},"n1819848928":{"id":"n1819848928","loc":[-85.648223,41.9829654]},"n1819848929":{"id":"n1819848929","loc":[-85.6514846,41.9659122]},"n1819848931":{"id":"n1819848931","loc":[-85.6498753,41.9731871]},"n1819848932":{"id":"n1819848932","loc":[-85.640906,41.9508575]},"n1819848933":{"id":"n1819848933","loc":[-85.649775,41.9799767]},"n1819848934":{"id":"n1819848934","loc":[-85.6507014,41.9739927]},"n1819848937":{"id":"n1819848937","loc":[-85.6479763,41.9840899]},"n1819848938":{"id":"n1819848938","loc":[-85.6501113,41.9600884]},"n1819848939":{"id":"n1819848939","loc":[-85.6389962,41.9478253]},"n1819848941":{"id":"n1819848941","loc":[-85.637469,41.9445791]},"n1819848942":{"id":"n1819848942","loc":[-85.6494569,41.9601682]},"n1819848943":{"id":"n1819848943","loc":[-85.6368803,41.9439351]},"n1819848945":{"id":"n1819848945","loc":[-85.6474398,41.9724213]},"n1819848946":{"id":"n1819848946","loc":[-85.6382629,41.9463666]},"n1819848948":{"id":"n1819848948","loc":[-85.6489633,41.9830771]},"n1819848952":{"id":"n1819848952","loc":[-85.6488882,41.9600326]},"n1819848953":{"id":"n1819848953","loc":[-85.6488094,41.9774324]},"n1819848954":{"id":"n1819848954","loc":[-85.6491135,41.9600485]},"n1819848955":{"id":"n1819848955","loc":[-85.6501435,41.9734583]},"n1819848956":{"id":"n1819848956","loc":[-85.6495534,41.960958]},"n1819848958":{"id":"n1819848958","loc":[-85.6474683,41.9561491]},"n1819848959":{"id":"n1819848959","loc":[-85.6401083,41.9485451]},"n1819848960":{"id":"n1819848960","loc":[-85.6481764,41.9678686]},"n1819848961":{"id":"n1819848961","loc":[-85.6484017,41.967382]},"n1819848962":{"id":"n1819848962","loc":[-85.6501328,41.959897]},"n1819848964":{"id":"n1819848964","loc":[-85.6403695,41.9504586]},"n1819848966":{"id":"n1819848966","loc":[-85.6398975,41.9491499]},"n1819848967":{"id":"n1819848967","loc":[-85.6412455,41.9510187]},"n1819848968":{"id":"n1819848968","loc":[-85.6482622,41.9619493]},"n1819848969":{"id":"n1819848969","loc":[-85.6405841,41.9501474]},"n1819848970":{"id":"n1819848970","loc":[-85.6478583,41.9703394]},"n1819848971":{"id":"n1819848971","loc":[-85.6493388,41.9832845]},"n1819848972":{"id":"n1819848972","loc":[-85.6485664,41.9829415]},"n1819848974":{"id":"n1819848974","loc":[-85.6491457,41.9779887]},"n1819848975":{"id":"n1819848975","loc":[-85.6468889,41.9697033]},"n1819848976":{"id":"n1819848976","loc":[-85.6452726,41.9546072]},"n1819848977":{"id":"n1819848977","loc":[-85.6448435,41.9546072]},"n1819848979":{"id":"n1819848979","loc":[-85.6485342,41.9763138]},"n1819848980":{"id":"n1819848980","loc":[-85.6495282,41.9664087]},"n1819848986":{"id":"n1819848986","loc":[-85.6486307,41.9603278]},"n1819848987":{"id":"n1819848987","loc":[-85.6492278,41.9791871]},"n1819848990":{"id":"n1819848990","loc":[-85.6501934,41.9800724]},"n1819848992":{"id":"n1819848992","loc":[-85.6482445,41.9819685]},"n1819848993":{"id":"n1819848993","loc":[-85.6481871,41.9704451]},"n1819848994":{"id":"n1819848994","loc":[-85.6371364,41.9457602]},"n1819848996":{"id":"n1819848996","loc":[-85.6500362,41.9801023]},"n1819849000":{"id":"n1819849000","loc":[-85.639007,41.9485914]},"n1819849001":{"id":"n1819849001","loc":[-85.6488882,41.9669253]},"n1819849002":{"id":"n1819849002","loc":[-85.6484698,41.9565062]},"n1819849004":{"id":"n1819849004","loc":[-85.6510769,41.9761064]},"n1819849005":{"id":"n1819849005","loc":[-85.6503581,41.9799029]},"n1819849006":{"id":"n1819849006","loc":[-85.6489381,41.9703893]},"n1819849008":{"id":"n1819849008","loc":[-85.6497457,41.9833588]},"n1819849011":{"id":"n1819849011","loc":[-85.6497358,41.9717593]},"n1819849012":{"id":"n1819849012","loc":[-85.6494676,41.9796796]},"n1819849019":{"id":"n1819849019","loc":[-85.6486093,41.9771034]},"n1819849021":{"id":"n1819849021","loc":[-85.6504546,41.9796556]},"n1819849022":{"id":"n1819849022","loc":[-85.6371294,41.9454154]},"n1819849023":{"id":"n1819849023","loc":[-85.6503436,41.9759249]},"n1819849025":{"id":"n1819849025","loc":[-85.6462382,41.9693822]},"n1819849026":{"id":"n1819849026","loc":[-85.6497573,41.983093]},"n1819849028":{"id":"n1819849028","loc":[-85.6497465,41.9602799]},"n1819849029":{"id":"n1819849029","loc":[-85.6374728,41.9460698]},"n1819849030":{"id":"n1819849030","loc":[-85.6486592,41.9566039]},"n1819849031":{"id":"n1819849031","loc":[-85.6515989,41.9654993]},"n1819849032":{"id":"n1819849032","loc":[-85.6387028,41.9482658]},"n1819849033":{"id":"n1819849033","loc":[-85.6464742,41.9688398]},"n1819849034":{"id":"n1819849034","loc":[-85.6495212,41.9589236]},"n1819849035":{"id":"n1819849035","loc":[-85.6490599,41.9790096]},"n1819849036":{"id":"n1819849036","loc":[-85.6489918,41.9800724]},"n1819849038":{"id":"n1819849038","loc":[-85.6499182,41.9659042]},"n1819849040":{"id":"n1819849040","loc":[-85.639758,41.9490143]},"n1819849041":{"id":"n1819849041","loc":[-85.6514846,41.9755241]},"n1819849042":{"id":"n1819849042","loc":[-85.6436633,41.9540647]},"n1819849045":{"id":"n1819849045","loc":[-85.6475541,41.9726387]},"n1819849046":{"id":"n1819849046","loc":[-85.6488308,41.9718331]},"n1819849047":{"id":"n1819849047","loc":[-85.6377694,41.9460953]},"n1819849048":{"id":"n1819849048","loc":[-85.6490706,41.9804452]},"n1819849049":{"id":"n1819849049","loc":[-85.6485449,41.9766248]},"n1819849051":{"id":"n1819849051","loc":[-85.6483625,41.9790256]},"n1819849052":{"id":"n1819849052","loc":[-85.6490706,41.9585167]},"n1819849053":{"id":"n1819849053","loc":[-85.6425008,41.9522874]},"n1819849054":{"id":"n1819849054","loc":[-85.6475793,41.9632158]},"n1819849055":{"id":"n1819849055","loc":[-85.6408631,41.9499399]},"n1819849056":{"id":"n1819849056","loc":[-85.6483373,41.9814681]},"n1819849057":{"id":"n1819849057","loc":[-85.6313548,41.9442876]},"n1819849058":{"id":"n1819849058","loc":[-85.6432663,41.9529796]},"n1819849059":{"id":"n1819849059","loc":[-85.6487128,41.9582873]},"n1819849060":{"id":"n1819849060","loc":[-85.6482338,41.9817612]},"n1819849062":{"id":"n1819849062","loc":[-85.6485664,41.9788661]},"n1819849063":{"id":"n1819849063","loc":[-85.6373081,41.9448824]},"n1819849064":{"id":"n1819849064","loc":[-85.6472215,41.9557582]},"n1819849065":{"id":"n1819849065","loc":[-85.6348984,41.9440414]},"n1819849066":{"id":"n1819849066","loc":[-85.6501972,41.9647315]},"n1819849067":{"id":"n1819849067","loc":[-85.6489741,41.9808281]},"n1819849068":{"id":"n1819849068","loc":[-85.6420111,41.9515034]},"n1819849069":{"id":"n1819849069","loc":[-85.6397972,41.9488882]},"n1819849070":{"id":"n1819849070","loc":[-85.6499718,41.9593465]},"n1819849071":{"id":"n1819849071","loc":[-85.6486844,41.9811311]},"n1819849072":{"id":"n1819849072","loc":[-85.6390392,41.9474663]},"n1819849074":{"id":"n1819849074","loc":[-85.6495642,41.9616362]},"n1819849075":{"id":"n1819849075","loc":[-85.6483518,41.9791931]},"n1819849076":{"id":"n1819849076","loc":[-85.6478974,41.9833104]},"n1819849077":{"id":"n1819849077","loc":[-85.640155,41.948719]},"n1819849078":{"id":"n1819849078","loc":[-85.6399366,41.9487845]},"n1819849079":{"id":"n1819849079","loc":[-85.6492959,41.9825348]},"n1819849080":{"id":"n1819849080","loc":[-85.6505083,41.9648352]},"n1819849081":{"id":"n1819849081","loc":[-85.6492959,41.9645241]},"n1819849082":{"id":"n1819849082","loc":[-85.6402049,41.9491835]},"n1819849083":{"id":"n1819849083","loc":[-85.6495175,41.9826963]},"n1819849084":{"id":"n1819849084","loc":[-85.6480836,41.9728361]},"n1819849085":{"id":"n1819849085","loc":[-85.6374349,41.9443425]},"n1819849086":{"id":"n1819849086","loc":[-85.6478331,41.9681238]},"n1819849089":{"id":"n1819849089","loc":[-85.639368,41.9486169]},"n1819849092":{"id":"n1819849092","loc":[-85.6503581,41.9788022]},"n1819849093":{"id":"n1819849093","loc":[-85.64862,41.9568014]},"n1819849094":{"id":"n1819849094","loc":[-85.6496999,41.9828877]},"n1819849095":{"id":"n1819849095","loc":[-85.647472,41.972198]},"n1819849096":{"id":"n1819849096","loc":[-85.6485771,41.9644523]},"n1819849097":{"id":"n1819849097","loc":[-85.6388353,41.9480488]},"n1819849099":{"id":"n1819849099","loc":[-85.6472752,41.9683312]},"n1819849104":{"id":"n1819849104","loc":[-85.6479548,41.9836035]},"n1819849105":{"id":"n1819849105","loc":[-85.6462489,41.9691668]},"n1819849107":{"id":"n1819849107","loc":[-85.6511912,41.9746328]},"n1819849108":{"id":"n1819849108","loc":[-85.6498646,41.9714881]},"n1819849111":{"id":"n1819849111","loc":[-85.6488239,41.961684]},"n1819849112":{"id":"n1819849112","loc":[-85.6469356,41.9553812]},"n1819849114":{"id":"n1819849114","loc":[-85.6479548,41.9640853]},"n1819849119":{"id":"n1819849119","loc":[-85.6491565,41.961692]},"n1819849121":{"id":"n1819849121","loc":[-85.651667,41.9656728]},"n1819849124":{"id":"n1819849124","loc":[-85.6388423,41.9484414]},"n1819849126":{"id":"n1819849126","loc":[-85.6371686,41.9450978]},"n1819849127":{"id":"n1819849127","loc":[-85.6502615,41.9656728]},"n1819849129":{"id":"n1819849129","loc":[-85.6498501,41.9613031]},"n1819849131":{"id":"n1819849131","loc":[-85.6513881,41.9653298]},"n1819849133":{"id":"n1819849133","loc":[-85.639883,41.9485291]},"n1819849139":{"id":"n1819849139","loc":[-85.6508693,41.9658264]},"n1819849140":{"id":"n1819849140","loc":[-85.6486806,41.9761642]},"n1819849141":{"id":"n1819849141","loc":[-85.6483159,41.9717613]},"n1819849144":{"id":"n1819849144","loc":[-85.6443714,41.9546232]},"n1819849146":{"id":"n1819849146","loc":[-85.641775,41.9513359]},"n1819849147":{"id":"n1819849147","loc":[-85.6495604,41.9757335]},"n1819849148":{"id":"n1819849148","loc":[-85.6465671,41.9551678]},"n1819849150":{"id":"n1819849150","loc":[-85.6485127,41.9794084]},"n1819849151":{"id":"n1819849151","loc":[-85.6499144,41.9757096]},"n1819849152":{"id":"n1819849152","loc":[-85.6433736,41.9531072]},"n1819849154":{"id":"n1819849154","loc":[-85.6489741,41.9607426]},"n1819849155":{"id":"n1819849155","loc":[-85.640627,41.9507697]},"n1819849156":{"id":"n1819849156","loc":[-85.6509659,41.9743058]},"n1819849157":{"id":"n1819849157","loc":[-85.6486844,41.9704431]},"n1819849158":{"id":"n1819849158","loc":[-85.6498538,41.9711132]},"n1819849159":{"id":"n1819849159","loc":[-85.6358937,41.943719]},"n1819849160":{"id":"n1819849160","loc":[-85.6497358,41.9707702]},"n1819849161":{"id":"n1819849161","loc":[-85.6480476,41.9564842]},"n1819849162":{"id":"n1819849162","loc":[-85.6482982,41.9574556]},"n1819849163":{"id":"n1819849163","loc":[-85.6501757,41.9757794]},"n1819849164":{"id":"n1819849164","loc":[-85.6372973,41.9459916]},"n1819849165":{"id":"n1819849165","loc":[-85.6513773,41.9750775]},"n1819849166":{"id":"n1819849166","loc":[-85.6436418,41.9537455]},"n1819849167":{"id":"n1819849167","loc":[-85.6483625,41.9571524]},"n1819849169":{"id":"n1819849169","loc":[-85.647751,41.9727962]},"n1819849170":{"id":"n1819849170","loc":[-85.6504546,41.9656808]},"n1819849171":{"id":"n1819849171","loc":[-85.6479977,41.971839]},"n1819849172":{"id":"n1819849172","loc":[-85.6482767,41.9642449]},"n1819849174":{"id":"n1819849174","loc":[-85.6414317,41.9512086]},"n1819849176":{"id":"n1819849176","loc":[-85.6469034,41.9685287]},"n1819849179":{"id":"n1819849179","loc":[-85.6408631,41.9497564]},"n1819849182":{"id":"n1819849182","loc":[-85.6476721,41.96384]},"n1819849183":{"id":"n1819849183","loc":[-85.6479725,41.983111]},"n1819849184":{"id":"n1819849184","loc":[-85.640788,41.9500516]},"n1819849185":{"id":"n1819849185","loc":[-85.6427798,41.9528778]},"n1819849186":{"id":"n1819849186","loc":[-85.6435308,41.9534124]},"n1819849187":{"id":"n1819849187","loc":[-85.6483733,41.9821998]},"n1819849189":{"id":"n1819849189","loc":[-85.6351752,41.9440796]},"n1819849191":{"id":"n1819849191","loc":[-85.6487021,41.9601463]},"n1819849192":{"id":"n1819849192","loc":[-85.6363811,41.9437605]},"n1819849193":{"id":"n1819849193","loc":[-85.6490883,41.9759728]},"n1819849194":{"id":"n1819849194","loc":[-85.6423292,41.9520081]},"n1819849195":{"id":"n1819849195","loc":[-85.6500003,41.960242]},"n1819849196":{"id":"n1819849196","loc":[-85.6385778,41.9466443]},"n1819849197":{"id":"n1819849197","loc":[-85.6494032,41.9718789]},"n1819849198":{"id":"n1819849198","loc":[-85.6404339,41.9506501]},"n1819849199":{"id":"n1819849199","loc":[-85.6426226,41.9527083]},"n1819849200":{"id":"n1819849200","loc":[-85.6439101,41.9545035]},"n1819849201":{"id":"n1819849201","loc":[-85.6516563,41.9657845]},"n1819849202":{"id":"n1819849202","loc":[-85.6473395,41.9699585]},"n1819858501":{"id":"n1819858501","loc":[-85.6361263,41.9437126]},"n1819858503":{"id":"n1819858503","loc":[-85.6350068,41.944034]},"n1819858513":{"id":"n1819858513","loc":[-85.6371402,41.9453282]},"n1819858518":{"id":"n1819858518","loc":[-85.6348713,41.9432923]},"n1819858523":{"id":"n1819858523","loc":[-85.6357047,41.943799]},"n1819858526":{"id":"n1819858526","loc":[-85.6349947,41.9435756]},"n1819858531":{"id":"n1819858531","loc":[-85.6350376,41.943827]},"n1820937508":{"id":"n1820937508","loc":[-85.1026013,42.0881722]},"n1820937509":{"id":"n1820937509","loc":[-85.0558088,42.102493]},"n1820937511":{"id":"n1820937511","loc":[-85.3030116,41.9724451]},"n1820937513":{"id":"n1820937513","loc":[-85.0353221,42.1027398]},"n1820937514":{"id":"n1820937514","loc":[-85.0835468,42.1015469]},"n1820937515":{"id":"n1820937515","loc":[-85.2421298,42.0106305]},"n1820937517":{"id":"n1820937517","loc":[-85.0090632,42.0910452]},"n1820937518":{"id":"n1820937518","loc":[-85.086626,42.0948838]},"n1820937520":{"id":"n1820937520","loc":[-85.2552039,42.0015448]},"n1820937521":{"id":"n1820937521","loc":[-85.3739614,41.9969917]},"n1820937522":{"id":"n1820937522","loc":[-85.4831166,41.993898]},"n1820937523":{"id":"n1820937523","loc":[-85.0341084,42.0977657]},"n1820937524":{"id":"n1820937524","loc":[-85.3272802,41.9710333]},"n1820937525":{"id":"n1820937525","loc":[-85.2125568,42.0414521]},"n1820937526":{"id":"n1820937526","loc":[-85.3798022,41.9992458]},"n1820937527":{"id":"n1820937527","loc":[-85.2652021,41.999768]},"n1820937528":{"id":"n1820937528","loc":[-85.3852739,42.0004896]},"n1820937529":{"id":"n1820937529","loc":[-85.3911919,42.0030513]},"n1820937530":{"id":"n1820937530","loc":[-85.5440349,41.9717109]},"n1820937531":{"id":"n1820937531","loc":[-85.2790155,41.9911764]},"n1820937532":{"id":"n1820937532","loc":[-85.4723277,41.9950518]},"n1820937533":{"id":"n1820937533","loc":[-85.5690546,41.9653931]},"n1820937535":{"id":"n1820937535","loc":[-85.5674882,41.9649623]},"n1820937536":{"id":"n1820937536","loc":[-85.6362815,41.9189165]},"n1820937537":{"id":"n1820937537","loc":[-85.5659003,41.963638]},"n1820937539":{"id":"n1820937539","loc":[-85.6391353,41.9122262]},"n1820937540":{"id":"n1820937540","loc":[-85.4834385,41.9894803]},"n1820937541":{"id":"n1820937541","loc":[-85.6399078,41.9160744]},"n1820937542":{"id":"n1820937542","loc":[-85.632874,41.941031]},"n1820937543":{"id":"n1820937543","loc":[-85.1307591,42.0726961]},"n1820937544":{"id":"n1820937544","loc":[-85.6444397,41.9128378]},"n1820937545":{"id":"n1820937545","loc":[-85.6197204,41.9420365]},"n1820937546":{"id":"n1820937546","loc":[-85.1164857,42.0864631]},"n1820937547":{"id":"n1820937547","loc":[-85.6476111,41.9142222]},"n1820937548":{"id":"n1820937548","loc":[-85.2915747,41.9774223]},"n1820937549":{"id":"n1820937549","loc":[-85.6430192,41.9102461]},"n1820937550":{"id":"n1820937550","loc":[-85.1597495,42.0639017]},"n1820937551":{"id":"n1820937551","loc":[-85.5504079,41.9701793]},"n1820937553":{"id":"n1820937553","loc":[-85.2781317,41.9948951]},"n1820937555":{"id":"n1820937555","loc":[-85.3724594,41.997518]},"n1820937556":{"id":"n1820937556","loc":[-85.5629434,41.9665155]},"n1820937557":{"id":"n1820937557","loc":[-85.3791971,41.9990808]},"n1820937558":{"id":"n1820937558","loc":[-85.001891,42.0878843]},"n1820937560":{"id":"n1820937560","loc":[-85.3140838,41.9709056]},"n1820937561":{"id":"n1820937561","loc":[-85.2468032,42.0146987]},"n1820937563":{"id":"n1820937563","loc":[-85.0877378,42.097255]},"n1820937564":{"id":"n1820937564","loc":[-85.2442498,42.0150654]},"n1820937566":{"id":"n1820937566","loc":[-85.3108973,41.9701478]},"n1820937568":{"id":"n1820937568","loc":[-85.0344584,42.1016572]},"n1820937569":{"id":"n1820937569","loc":[-85.2331025,42.0297387]},"n1820937570":{"id":"n1820937570","loc":[-85.5058446,41.9746996]},"n1820937571":{"id":"n1820937571","loc":[-85.5622739,41.9676427]},"n1820937572":{"id":"n1820937572","loc":[-85.2792687,41.9890337]},"n1820937574":{"id":"n1820937574","loc":[-84.9909302,42.08695]},"n1820937575":{"id":"n1820937575","loc":[-85.6218233,41.9418609]},"n1820937576":{"id":"n1820937576","loc":[-85.3577437,41.9931062]},"n1820937577":{"id":"n1820937577","loc":[-85.639028,41.9165853]},"n1820937578":{"id":"n1820937578","loc":[-84.9956576,42.0865348]},"n1820937579":{"id":"n1820937579","loc":[-85.4828376,41.990198]},"n1820937580":{"id":"n1820937580","loc":[-85.3244478,41.9720543]},"n1820937582":{"id":"n1820937582","loc":[-85.0517479,42.1035159]},"n1820937583":{"id":"n1820937583","loc":[-85.225646,42.0338025]},"n1820937584":{"id":"n1820937584","loc":[-84.9941019,42.0862163]},"n1820937586":{"id":"n1820937586","loc":[-85.1051762,42.0879452]},"n1820937587":{"id":"n1820937587","loc":[-85.1245203,42.0753162]},"n1820937588":{"id":"n1820937588","loc":[-85.3250808,41.9719506]},"n1820937589":{"id":"n1820937589","loc":[-85.2720109,41.997933]},"n1820937590":{"id":"n1820937590","loc":[-85.2556653,42.0027248]},"n1820937591":{"id":"n1820937591","loc":[-85.0872483,42.0943544]},"n1820937592":{"id":"n1820937592","loc":[-85.2778353,41.9955023]},"n1820937593":{"id":"n1820937593","loc":[-85.2984733,41.9735538]},"n1820937594":{"id":"n1820937594","loc":[-85.101578,42.0889552]},"n1820937595":{"id":"n1820937595","loc":[-85.3888745,42.0016959]},"n1820937596":{"id":"n1820937596","loc":[-84.9903508,42.0870654]},"n1820937597":{"id":"n1820937597","loc":[-85.6405558,41.9146261]},"n1820937598":{"id":"n1820937598","loc":[-85.6460704,41.9141311]},"n1820937599":{"id":"n1820937599","loc":[-85.0377468,42.1037428]},"n1820937600":{"id":"n1820937600","loc":[-85.2298345,42.0312899]},"n1820937601":{"id":"n1820937601","loc":[-85.1080958,42.0861964]},"n1820937602":{"id":"n1820937602","loc":[-85.6325307,41.9402329]},"n1820937603":{"id":"n1820937603","loc":[-85.1165984,42.0832184]},"n1820937604":{"id":"n1820937604","loc":[-85.6354446,41.9190602]},"n1820937605":{"id":"n1820937605","loc":[-85.1114592,42.0862959]},"n1820937606":{"id":"n1820937606","loc":[-85.0858763,42.1001646]},"n1820937607":{"id":"n1820937607","loc":[-85.0472083,42.1015151]},"n1820937608":{"id":"n1820937608","loc":[-85.0802477,42.1027609]},"n1820937610":{"id":"n1820937610","loc":[-85.0924585,42.0928564]},"n1820937611":{"id":"n1820937611","loc":[-85.0329617,42.09827]},"n1820937612":{"id":"n1820937612","loc":[-85.2814617,41.993465]},"n1820937613":{"id":"n1820937613","loc":[-85.3097708,41.9700282]},"n1820937614":{"id":"n1820937614","loc":[-85.2809427,41.993695]},"n1820937615":{"id":"n1820937615","loc":[-85.0583233,42.1026494]},"n1820937617":{"id":"n1820937617","loc":[-85.2801592,41.9840021]},"n1820937619":{"id":"n1820937619","loc":[-85.1064154,42.0863449]},"n1820937620":{"id":"n1820937620","loc":[-85.0423173,42.1014662]},"n1820937621":{"id":"n1820937621","loc":[-85.2168913,42.0398107]},"n1820937622":{"id":"n1820937622","loc":[-85.2798481,41.9833401]},"n1820937623":{"id":"n1820937623","loc":[-85.0575468,42.1028672]},"n1820937625":{"id":"n1820937625","loc":[-85.0130369,42.0893067]},"n1820937626":{"id":"n1820937626","loc":[-85.0346985,42.1018256]},"n1820937627":{"id":"n1820937627","loc":[-85.2231569,42.0372768]},"n1820937628":{"id":"n1820937628","loc":[-85.2956195,41.9732268]},"n1820937629":{"id":"n1820937629","loc":[-85.1052312,42.086893]},"n1820937630":{"id":"n1820937630","loc":[-85.4813356,41.9958436]},"n1820937631":{"id":"n1820937631","loc":[-85.0961599,42.0914672]},"n1820937632":{"id":"n1820937632","loc":[-85.308419,41.9704749]},"n1820937633":{"id":"n1820937633","loc":[-85.295952,41.9715119]},"n1820937634":{"id":"n1820937634","loc":[-85.3310933,41.9703923]},"n1820937635":{"id":"n1820937635","loc":[-85.2940745,41.9739686]},"n1820937636":{"id":"n1820937636","loc":[-85.3803343,42.000484]},"n1820937637":{"id":"n1820937637","loc":[-85.1174231,42.0845533]},"n1820937638":{"id":"n1820937638","loc":[-85.0095836,42.089839]},"n1820937639":{"id":"n1820937639","loc":[-85.3179354,41.9705866]},"n1820937640":{"id":"n1820937640","loc":[-85.257708,42.0001189]},"n1820937641":{"id":"n1820937641","loc":[-85.2563522,42.0002771]},"n1820937642":{"id":"n1820937642","loc":[-85.3181929,41.970419]},"n1820937643":{"id":"n1820937643","loc":[-85.2911884,41.9757154]},"n1820937644":{"id":"n1820937644","loc":[-85.2714423,41.9975862]},"n1820937645":{"id":"n1820937645","loc":[-85.0193669,42.089888]},"n1820937646":{"id":"n1820937646","loc":[-85.3889818,42.0039921]},"n1820937647":{"id":"n1820937647","loc":[-85.3408093,41.9853965]},"n1820937648":{"id":"n1820937648","loc":[-85.1258091,42.0748332]},"n1820937649":{"id":"n1820937649","loc":[-85.5722561,41.962782]},"n1820937650":{"id":"n1820937650","loc":[-85.3266902,41.9721819]},"n1820937651":{"id":"n1820937651","loc":[-85.1473255,42.065192]},"n1820937652":{"id":"n1820937652","loc":[-85.1462526,42.0655106]},"n1820937653":{"id":"n1820937653","loc":[-85.4641051,42.0013929]},"n1820937654":{"id":"n1820937654","loc":[-85.5620379,41.9700677]},"n1820937655":{"id":"n1820937655","loc":[-85.3226025,41.971121]},"n1820937656":{"id":"n1820937656","loc":[-85.0200965,42.0899516]},"n1820937657":{"id":"n1820937657","loc":[-85.0624714,42.1044711]},"n1820937658":{"id":"n1820937658","loc":[-85.5649562,41.9637178]},"n1820937659":{"id":"n1820937659","loc":[-85.2360315,42.0253315]},"n1820937660":{"id":"n1820937660","loc":[-85.3881449,41.9994475]},"n1820937661":{"id":"n1820937661","loc":[-85.5032911,41.976263]},"n1820937662":{"id":"n1820937662","loc":[-85.481297,41.9871414]},"n1820937663":{"id":"n1820937663","loc":[-85.1167056,42.0841898]},"n1820937664":{"id":"n1820937664","loc":[-85.2891714,41.9787223]},"n1820937665":{"id":"n1820937665","loc":[-85.4393429,42.0058736]},"n1820937666":{"id":"n1820937666","loc":[-85.0077007,42.0895762]},"n1820937667":{"id":"n1820937667","loc":[-85.2736202,41.9979171]},"n1820937668":{"id":"n1820937668","loc":[-84.9935332,42.0859296]},"n1820937669":{"id":"n1820937669","loc":[-85.0622769,42.1046713]},"n1820937670":{"id":"n1820937670","loc":[-85.2309031,42.0311249]},"n1820937671":{"id":"n1820937671","loc":[-85.0343726,42.10069]},"n1820937672":{"id":"n1820937672","loc":[-85.0596551,42.1048612]},"n1820937673":{"id":"n1820937673","loc":[-85.1338597,42.0707449]},"n1820937674":{"id":"n1820937674","loc":[-85.3117663,41.9689194]},"n1820937675":{"id":"n1820937675","loc":[-85.0705649,42.1057499]},"n1820937676":{"id":"n1820937676","loc":[-85.2441425,42.0180944]},"n1820937677":{"id":"n1820937677","loc":[-85.1171174,42.0862692]},"n1820937678":{"id":"n1820937678","loc":[-85.0346824,42.1005519]},"n1820937680":{"id":"n1820937680","loc":[-85.2389927,42.0229245]},"n1820937681":{"id":"n1820937681","loc":[-85.0834892,42.1018642]},"n1820937682":{"id":"n1820937682","loc":[-85.0619443,42.1049459]},"n1820937683":{"id":"n1820937683","loc":[-85.2845366,41.9811868]},"n1820937684":{"id":"n1820937684","loc":[-85.210411,42.0394123]},"n1820937685":{"id":"n1820937685","loc":[-85.4377383,42.0055942]},"n1820937686":{"id":"n1820937686","loc":[-85.2882058,41.9789138]},"n1820937687":{"id":"n1820937687","loc":[-85.2741191,41.9955808]},"n1820937688":{"id":"n1820937688","loc":[-85.3442211,41.9903575]},"n1820937689":{"id":"n1820937689","loc":[-85.2641413,41.9995237]},"n1820937690":{"id":"n1820937690","loc":[-85.2804489,41.9829174]},"n1820937691":{"id":"n1820937691","loc":[-85.5593342,41.9729074]},"n1820937692":{"id":"n1820937692","loc":[-85.3590912,41.9932601]},"n1820937694":{"id":"n1820937694","loc":[-85.4826445,41.9957479]},"n1820937695":{"id":"n1820937695","loc":[-85.4539127,42.0063041]},"n1820937696":{"id":"n1820937696","loc":[-85.2456767,42.0153683]},"n1820937697":{"id":"n1820937697","loc":[-85.5794015,41.9489631]},"n1820937698":{"id":"n1820937698","loc":[-85.4108686,42.0078507]},"n1820937699":{"id":"n1820937699","loc":[-85.0616386,42.1051529]},"n1820937700":{"id":"n1820937700","loc":[-85.4977979,41.978241]},"n1820937701":{"id":"n1820937701","loc":[-85.2488417,42.0086319]},"n1820937702":{"id":"n1820937702","loc":[-85.5588836,41.9728116]},"n1820937703":{"id":"n1820937703","loc":[-85.4557366,42.0051241]},"n1820937705":{"id":"n1820937705","loc":[-85.0723151,42.1056094]},"n1820937706":{"id":"n1820937706","loc":[-85.0057909,42.0887323]},"n1820937707":{"id":"n1820937707","loc":[-85.0756786,42.105677]},"n1820937708":{"id":"n1820937708","loc":[-85.0901504,42.0940001]},"n1820937709":{"id":"n1820937709","loc":[-85.0979999,42.0910213]},"n1820937710":{"id":"n1820937710","loc":[-85.2376301,42.0239686]},"n1820937711":{"id":"n1820937711","loc":[-85.2780671,41.9902299]},"n1820937712":{"id":"n1820937712","loc":[-85.251481,42.0113188]},"n1820937713":{"id":"n1820937713","loc":[-85.3114767,41.9690311]},"n1820937714":{"id":"n1820937714","loc":[-85.2649621,41.9975662]},"n1820937715":{"id":"n1820937715","loc":[-85.283807,41.9813383]},"n1820937716":{"id":"n1820937716","loc":[-85.5515451,41.9703867]},"n1820937717":{"id":"n1820937717","loc":[-85.1176605,42.0850896]},"n1820937718":{"id":"n1820937718","loc":[-85.1069317,42.0862441]},"n1820937719":{"id":"n1820937719","loc":[-85.2739314,41.9976938]},"n1820937720":{"id":"n1820937720","loc":[-85.5550212,41.9702112]},"n1820937721":{"id":"n1820937721","loc":[-85.3076679,41.9719904]},"n1820937722":{"id":"n1820937722","loc":[-85.592319,41.9440316]},"n1820937723":{"id":"n1820937723","loc":[-85.3139979,41.9704031]},"n1820937724":{"id":"n1820937724","loc":[-85.0421134,42.1013149]},"n1820937725":{"id":"n1820937725","loc":[-85.2508373,42.0102741]},"n1820937726":{"id":"n1820937726","loc":[-85.0830922,42.1038821]},"n1820937727":{"id":"n1820937727","loc":[-85.6342473,41.9360031]},"n1820937730":{"id":"n1820937730","loc":[-85.0500192,42.1024942]},"n1820937731":{"id":"n1820937731","loc":[-85.3498644,41.9926221]},"n1820937732":{"id":"n1820937732","loc":[-85.0234117,42.0918903]},"n1820937733":{"id":"n1820937733","loc":[-85.0464425,42.1009408]},"n1820937734":{"id":"n1820937734","loc":[-85.033938,42.099886]},"n1820937736":{"id":"n1820937736","loc":[-85.0152752,42.0886009]},"n1820937737":{"id":"n1820937737","loc":[-85.0441894,42.1012671]},"n1820937738":{"id":"n1820937738","loc":[-85.4668731,41.9979804]},"n1820937739":{"id":"n1820937739","loc":[-85.4407377,42.006033]},"n1820937740":{"id":"n1820937740","loc":[-85.2262253,42.0344878]},"n1820937741":{"id":"n1820937741","loc":[-85.2550001,42.0033706]},"n1820937742":{"id":"n1820937742","loc":[-85.3071422,41.9722617]},"n1820937743":{"id":"n1820937743","loc":[-85.6147852,41.942228]},"n1820937744":{"id":"n1820937744","loc":[-85.0183853,42.0901825]},"n1820937745":{"id":"n1820937745","loc":[-85.6323161,41.9228489]},"n1820937746":{"id":"n1820937746","loc":[-85.0095568,42.0901376]},"n1820937747":{"id":"n1820937747","loc":[-85.2524037,42.0113826]},"n1820937748":{"id":"n1820937748","loc":[-85.3186864,41.9708578]},"n1820937749":{"id":"n1820937749","loc":[-85.2805669,41.9870883]},"n1820937750":{"id":"n1820937750","loc":[-85.0585768,42.1038144]},"n1820937751":{"id":"n1820937751","loc":[-85.2970786,41.9715358]},"n1820937752":{"id":"n1820937752","loc":[-85.1315758,42.0723445]},"n1820937753":{"id":"n1820937753","loc":[-85.2448291,42.0175444]},"n1820937754":{"id":"n1820937754","loc":[-85.2446468,42.0174248]},"n1820937755":{"id":"n1820937755","loc":[-85.229165,42.032129]},"n1820937756":{"id":"n1820937756","loc":[-85.5612654,41.9724926]},"n1820937757":{"id":"n1820937757","loc":[-85.2331776,42.030854]},"n1820937758":{"id":"n1820937758","loc":[-85.2271909,42.0334519]},"n1820937759":{"id":"n1820937759","loc":[-85.1032396,42.0879214]},"n1820937760":{"id":"n1820937760","loc":[-85.0638447,42.1044154]},"n1820937761":{"id":"n1820937761","loc":[-85.1260706,42.0745556]},"n1820937762":{"id":"n1820937762","loc":[-85.3454485,41.99132]},"n1820937763":{"id":"n1820937763","loc":[-85.2639321,41.9980088]},"n1820937764":{"id":"n1820937764","loc":[-85.0837681,42.1013746]},"n1820937765":{"id":"n1820937765","loc":[-85.2808137,41.9869368]},"n1820937766":{"id":"n1820937766","loc":[-85.6338997,41.9309373]},"n1820937767":{"id":"n1820937767","loc":[-85.2267403,42.0332766]},"n1820937768":{"id":"n1820937768","loc":[-85.0605831,42.1052074]},"n1820937769":{"id":"n1820937769","loc":[-85.0259021,42.0930037]},"n1820937770":{"id":"n1820937770","loc":[-85.232963,42.0313162]},"n1820937771":{"id":"n1820937771","loc":[-85.2404947,42.0125381]},"n1820937772":{"id":"n1820937772","loc":[-85.0910892,42.0935742]},"n1820937773":{"id":"n1820937773","loc":[-85.2554829,42.0019435]},"n1820937774":{"id":"n1820937774","loc":[-85.2799339,41.9867773]},"n1820937775":{"id":"n1820937775","loc":[-85.1075432,42.0852767]},"n1820937776":{"id":"n1820937776","loc":[-85.1176927,42.0854001]},"n1820937777":{"id":"n1820937777","loc":[-85.1067064,42.0863357]},"n1820937778":{"id":"n1820937778","loc":[-85.2517492,42.0106333]},"n1820937779":{"id":"n1820937779","loc":[-85.0987174,42.0909031]},"n1820937780":{"id":"n1820937780","loc":[-85.1160083,42.0863994]},"n1820937781":{"id":"n1820937781","loc":[-85.1268645,42.0739703]},"n1820937782":{"id":"n1820937782","loc":[-85.0454702,42.1002852]},"n1820937783":{"id":"n1820937783","loc":[-85.1334145,42.0705418]},"n1820937784":{"id":"n1820937784","loc":[-85.5866542,41.947431]},"n1820937786":{"id":"n1820937786","loc":[-85.2359886,42.0250366]},"n1820937787":{"id":"n1820937787","loc":[-85.3138048,41.9698527]},"n1820937788":{"id":"n1820937788","loc":[-85.1274291,42.0733081]},"n1820937790":{"id":"n1820937790","loc":[-85.6292905,41.9411267]},"n1820937791":{"id":"n1820937791","loc":[-85.5958809,41.9417333]},"n1820937792":{"id":"n1820937792","loc":[-85.1271019,42.0737581]},"n1820937793":{"id":"n1820937793","loc":[-85.2312679,42.0314437]},"n1820937794":{"id":"n1820937794","loc":[-85.1081387,42.0863516]},"n1820937795":{"id":"n1820937795","loc":[-85.2424473,42.0212109]},"n1820937796":{"id":"n1820937796","loc":[-85.2710654,41.9975236]},"n1820937797":{"id":"n1820937797","loc":[-85.4798408,41.9863223]},"n1820937798":{"id":"n1820937798","loc":[-85.035939,42.104296]},"n1820937799":{"id":"n1820937799","loc":[-85.2178139,42.0395398]},"n1820937800":{"id":"n1820937800","loc":[-85.0630709,42.1042614]},"n1820937801":{"id":"n1820937801","loc":[-85.0440124,42.1014861]},"n1820937802":{"id":"n1820937802","loc":[-85.1321874,42.0720458]},"n1820937804":{"id":"n1820937804","loc":[-85.079427,42.1029121]},"n1820937805":{"id":"n1820937805","loc":[-85.2962632,41.9738968]},"n1820937806":{"id":"n1820937806","loc":[-85.6334748,41.9274627]},"n1820937807":{"id":"n1820937807","loc":[-85.1057341,42.0872804]},"n1820937808":{"id":"n1820937808","loc":[-85.4960169,41.9778263]},"n1820937809":{"id":"n1820937809","loc":[-85.2821226,41.9910273]},"n1820937810":{"id":"n1820937810","loc":[-85.0013868,42.0885054]},"n1820937811":{"id":"n1820937811","loc":[-85.2952547,41.9729795]},"n1820937812":{"id":"n1820937812","loc":[-85.1298375,42.0667842]},"n1820937813":{"id":"n1820937813","loc":[-85.1339201,42.0710025]},"n1820937814":{"id":"n1820937814","loc":[-85.0374356,42.103691]},"n1820937815":{"id":"n1820937815","loc":[-85.0061115,42.0880607]},"n1820937817":{"id":"n1820937817","loc":[-85.2398402,42.0226934]},"n1820937818":{"id":"n1820937818","loc":[-85.123501,42.076236]},"n1820937819":{"id":"n1820937819","loc":[-85.1209489,42.0791294]},"n1820937820":{"id":"n1820937820","loc":[-85.0818624,42.1025778]},"n1820937821":{"id":"n1820937821","loc":[-85.4428835,42.0054749]},"n1820937822":{"id":"n1820937822","loc":[-85.4710359,41.9961147]},"n1820937823":{"id":"n1820937823","loc":[-85.4253354,42.006198]},"n1820937824":{"id":"n1820937824","loc":[-85.5486483,41.9709451]},"n1820937825":{"id":"n1820937825","loc":[-85.2303238,42.0310452]},"n1820937826":{"id":"n1820937826","loc":[-85.6450405,41.9136361]},"n1820937828":{"id":"n1820937828","loc":[-85.2606853,41.9964073]},"n1820937830":{"id":"n1820937830","loc":[-85.097383,42.0911447]},"n1820937831":{"id":"n1820937831","loc":[-85.0498207,42.102136]},"n1820937832":{"id":"n1820937832","loc":[-85.1232435,42.0763793]},"n1820937833":{"id":"n1820937833","loc":[-85.394093,42.0055921]},"n1820937834":{"id":"n1820937834","loc":[-85.3566665,41.9928295]},"n1820937835":{"id":"n1820937835","loc":[-85.3543276,41.9920002]},"n1820937837":{"id":"n1820937837","loc":[-85.084668,42.1034932]},"n1820937838":{"id":"n1820937838","loc":[-85.4400296,42.0060649]},"n1820937839":{"id":"n1820937839","loc":[-85.2362246,42.025714]},"n1820937840":{"id":"n1820937840","loc":[-85.0409225,42.1012791]},"n1820937841":{"id":"n1820937841","loc":[-85.2442283,42.019832]},"n1820937842":{"id":"n1820937842","loc":[-85.1123001,42.084824]},"n1820937843":{"id":"n1820937843","loc":[-85.1603074,42.0638061]},"n1820937844":{"id":"n1820937844","loc":[-85.1359744,42.0650646]},"n1820937845":{"id":"n1820937845","loc":[-85.1757569,42.053849]},"n1820937846":{"id":"n1820937846","loc":[-85.5200925,41.9716686]},"n1820937848":{"id":"n1820937848","loc":[-85.5525322,41.9701315]},"n1820937849":{"id":"n1820937849","loc":[-85.0406489,42.10149]},"n1820937850":{"id":"n1820937850","loc":[-85.0142547,42.088825]},"n1820937851":{"id":"n1820937851","loc":[-85.343749,41.9881884]},"n1820937852":{"id":"n1820937852","loc":[-85.074996,42.1060205]},"n1820937853":{"id":"n1820937853","loc":[-85.2436275,42.0136864]},"n1820937854":{"id":"n1820937854","loc":[-85.2641453,41.9980897]},"n1820937856":{"id":"n1820937856","loc":[-85.2802343,41.9870086]},"n1820937857":{"id":"n1820937857","loc":[-85.0099256,42.0909946]},"n1820937858":{"id":"n1820937858","loc":[-85.493957,41.9786079]},"n1820937859":{"id":"n1820937859","loc":[-85.0739405,42.1059795]},"n1820937860":{"id":"n1820937860","loc":[-85.2331605,42.0301423]},"n1820937862":{"id":"n1820937862","loc":[-85.2035231,42.0438425]},"n1820937863":{"id":"n1820937863","loc":[-85.0884928,42.0986971]},"n1820937864":{"id":"n1820937864","loc":[-85.131597,42.0690142]},"n1820937865":{"id":"n1820937865","loc":[-85.3937454,42.0052677]},"n1820937866":{"id":"n1820937866","loc":[-85.2212729,42.0378561]},"n1820937867":{"id":"n1820937867","loc":[-85.0886068,42.0982421]},"n1820937868":{"id":"n1820937868","loc":[-85.0875004,42.0968064]},"n1820937869":{"id":"n1820937869","loc":[-85.0771323,42.1042642]},"n1820937870":{"id":"n1820937870","loc":[-85.0164554,42.0894887]},"n1820937871":{"id":"n1820937871","loc":[-85.6069102,41.9415577]},"n1820937872":{"id":"n1820937872","loc":[-85.3273875,41.9704908]},"n1820937873":{"id":"n1820937873","loc":[-85.3890891,41.9997983]},"n1820937875":{"id":"n1820937875","loc":[-85.5091276,41.9723705]},"n1820937876":{"id":"n1820937876","loc":[-85.0770626,42.1047696]},"n1820937877":{"id":"n1820937877","loc":[-85.612575,41.9419567]},"n1820937878":{"id":"n1820937878","loc":[-85.3868146,42.0036094]},"n1820937879":{"id":"n1820937879","loc":[-85.2722738,41.9981204]},"n1820937880":{"id":"n1820937880","loc":[-85.3064878,41.9723733]},"n1820937882":{"id":"n1820937882","loc":[-85.1270845,42.0727678]},"n1820937884":{"id":"n1820937884","loc":[-85.3316512,41.97923]},"n1820937885":{"id":"n1820937885","loc":[-85.3932519,42.0042472]},"n1820937886":{"id":"n1820937886","loc":[-85.2457411,42.0175444]},"n1820937887":{"id":"n1820937887","loc":[-85.1397509,42.0648415]},"n1820937891":{"id":"n1820937891","loc":[-85.3196735,41.9719665]},"n1820937892":{"id":"n1820937892","loc":[-85.3372473,41.9845033]},"n1820937894":{"id":"n1820937894","loc":[-85.3254778,41.9719745]},"n1820937897":{"id":"n1820937897","loc":[-85.3185148,41.9691268]},"n1820937899":{"id":"n1820937899","loc":[-85.5419106,41.9714556]},"n1820937901":{"id":"n1820937901","loc":[-85.3293509,41.9748368]},"n1820937903":{"id":"n1820937903","loc":[-85.0798078,42.1028365]},"n1820937905":{"id":"n1820937905","loc":[-85.3954191,42.0056025]},"n1820937909":{"id":"n1820937909","loc":[-85.3417534,41.9857155]},"n1820937913":{"id":"n1820937913","loc":[-84.9927822,42.0857107]},"n1820937915":{"id":"n1820937915","loc":[-85.5444212,41.9712801]},"n1820937917":{"id":"n1820937917","loc":[-85.259088,41.9981682]},"n1820937921":{"id":"n1820937921","loc":[-85.2784576,41.9876358]},"n1820937922":{"id":"n1820937922","loc":[-84.9971918,42.087753]},"n1820937924":{"id":"n1820937924","loc":[-85.5310688,41.966899]},"n1820937928":{"id":"n1820937928","loc":[-85.3766436,41.9979326]},"n1820937930":{"id":"n1820937930","loc":[-85.5494852,41.9704346]},"n1820937933":{"id":"n1820937933","loc":[-85.5548281,41.9695412]},"n1820937935":{"id":"n1820937935","loc":[-85.0768588,42.105088]},"n1820937937":{"id":"n1820937937","loc":[-85.2646885,41.9978054]},"n1820937939":{"id":"n1820937939","loc":[-85.2441532,42.0176082]},"n1820937941":{"id":"n1820937941","loc":[-85.105553,42.0877928]},"n1820937943":{"id":"n1820937943","loc":[-85.0879457,42.0958909]},"n1820937944":{"id":"n1820937944","loc":[-85.3187015,41.9704402]},"n1820937945":{"id":"n1820937945","loc":[-85.5624456,41.970626]},"n1820937946":{"id":"n1820937946","loc":[-85.0580176,42.1028644]},"n1820937948":{"id":"n1820937948","loc":[-85.3016061,41.9726286]},"n1820937949":{"id":"n1820937949","loc":[-85.4310388,42.0069418]},"n1820937950":{"id":"n1820937950","loc":[-85.2945144,41.9740723]},"n1820937951":{"id":"n1820937951","loc":[-85.1170222,42.082657]},"n1820937952":{"id":"n1820937952","loc":[-85.0864503,42.0947632]},"n1820937953":{"id":"n1820937953","loc":[-85.4285926,42.0059533]},"n1820937970":{"id":"n1820937970","loc":[-85.3629965,41.9938023]},"n1820937972":{"id":"n1820937972","loc":[-85.2438099,42.0199755]},"n1820937974":{"id":"n1820937974","loc":[-85.1327654,42.0699285]},"n1820937977":{"id":"n1820937977","loc":[-85.1515956,42.0611935]},"n1820937978":{"id":"n1820937978","loc":[-85.0107369,42.0896638]},"n1820937979":{"id":"n1820937979","loc":[-85.1152626,42.0862083]},"n1820937980":{"id":"n1820937980","loc":[-85.4531831,42.0062881]},"n1820937981":{"id":"n1820937981","loc":[-85.0341473,42.0985924]},"n1820937982":{"id":"n1820937982","loc":[-85.0877485,42.0960171]},"n1820937983":{"id":"n1820937983","loc":[-85.2756373,41.9951742]},"n1820937984":{"id":"n1820937984","loc":[-85.2965421,41.9714401]},"n1820937985":{"id":"n1820937985","loc":[-85.2409775,42.0226934]},"n1820937986":{"id":"n1820937986","loc":[-85.0170723,42.0900579]},"n1820937987":{"id":"n1820937987","loc":[-85.1034663,42.0880555]},"n1820937988":{"id":"n1820937988","loc":[-85.0585071,42.1031577]},"n1820937990":{"id":"n1820937990","loc":[-85.0819174,42.1032373]},"n1820937992":{"id":"n1820937992","loc":[-85.0546608,42.1030542]},"n1820937993":{"id":"n1820937993","loc":[-85.0100811,42.0906125]},"n1820937995":{"id":"n1820937995","loc":[-85.6304278,41.9432655]},"n1820937997":{"id":"n1820937997","loc":[-85.0255628,42.092778]},"n1820938011":{"id":"n1820938011","loc":[-85.2316756,42.0317146]},"n1820938012":{"id":"n1820938012","loc":[-85.4067917,42.008042]},"n1820938013":{"id":"n1820938013","loc":[-85.390398,42.0028759]},"n1820938014":{"id":"n1820938014","loc":[-85.0161604,42.0886527]},"n1820938015":{"id":"n1820938015","loc":[-85.125337,42.0744589]},"n1820938016":{"id":"n1820938016","loc":[-85.2151317,42.0404801]},"n1820938017":{"id":"n1820938017","loc":[-85.3165085,41.9706025]},"n1820938018":{"id":"n1820938018","loc":[-85.5641193,41.9640688]},"n1820938019":{"id":"n1820938019","loc":[-85.147583,42.0642203]},"n1820938022":{"id":"n1820938022","loc":[-85.2803781,41.9947886]},"n1820938024":{"id":"n1820938024","loc":[-85.2692469,41.9982053]},"n1820938026":{"id":"n1820938026","loc":[-85.4321975,42.0067505]},"n1820938028":{"id":"n1820938028","loc":[-85.572535,41.9633405]},"n1820938030":{"id":"n1820938030","loc":[-85.3237505,41.9716475]},"n1820938032":{"id":"n1820938032","loc":[-85.6487698,41.9141583]},"n1820938033":{"id":"n1820938033","loc":[-85.0526371,42.1038315]},"n1820938034":{"id":"n1820938034","loc":[-85.088069,42.0978731]},"n1820938035":{"id":"n1820938035","loc":[-85.2516312,42.0102267]},"n1820938039":{"id":"n1820938039","loc":[-85.2731374,41.9982958]},"n1820938040":{"id":"n1820938040","loc":[-85.5453224,41.9713439]},"n1820938041":{"id":"n1820938041","loc":[-85.4480548,42.0049647]},"n1820938043":{"id":"n1820938043","loc":[-85.2504081,42.010322]},"n1820938045":{"id":"n1820938045","loc":[-85.2663447,41.99919]},"n1820938046":{"id":"n1820938046","loc":[-85.0507287,42.102907]},"n1820938047":{"id":"n1820938047","loc":[-85.0408246,42.1024743]},"n1820938048":{"id":"n1820938048","loc":[-85.2796335,41.9866099]},"n1820938050":{"id":"n1820938050","loc":[-85.452475,42.0061127]},"n1820938051":{"id":"n1820938051","loc":[-85.2410569,42.0128147]},"n1820938052":{"id":"n1820938052","loc":[-85.0413302,42.1011477]},"n1820938053":{"id":"n1820938053","loc":[-85.6327409,41.9197627]},"n1820938056":{"id":"n1820938056","loc":[-85.1072039,42.0857994]},"n1820938057":{"id":"n1820938057","loc":[-85.2001114,42.0448145]},"n1820938058":{"id":"n1820938058","loc":[-85.2655347,41.9978186]},"n1820938059":{"id":"n1820938059","loc":[-85.2330918,42.0304874]},"n1820938060":{"id":"n1820938060","loc":[-85.2601113,41.9966545]},"n1820938061":{"id":"n1820938061","loc":[-85.5397863,41.9708494]},"n1820938062":{"id":"n1820938062","loc":[-85.2702085,41.9977217]},"n1820938063":{"id":"n1820938063","loc":[-85.2219982,42.03699]},"n1820938064":{"id":"n1820938064","loc":[-85.0668957,42.105121]},"n1820938065":{"id":"n1820938065","loc":[-85.2328665,42.0270769]},"n1820938066":{"id":"n1820938066","loc":[-85.3189654,41.9694778]},"n1820938067":{"id":"n1820938067","loc":[-85.3814115,42.0022915]},"n1820938068":{"id":"n1820938068","loc":[-85.2759108,41.9956008]},"n1820938069":{"id":"n1820938069","loc":[-85.0391938,42.1034853]},"n1820938070":{"id":"n1820938070","loc":[-85.2850623,41.9810353]},"n1820938071":{"id":"n1820938071","loc":[-85.538074,41.970855]},"n1820938073":{"id":"n1820938073","loc":[-85.1319661,42.0670932]},"n1820938074":{"id":"n1820938074","loc":[-85.2816763,41.9913678]},"n1820938075":{"id":"n1820938075","loc":[-85.3182144,41.9700282]},"n1820938076":{"id":"n1820938076","loc":[-85.5909028,41.9458989]},"n1820938077":{"id":"n1820938077","loc":[-85.4057617,42.0074361]},"n1820938078":{"id":"n1820938078","loc":[-85.2620438,41.9967729]},"n1820938079":{"id":"n1820938079","loc":[-85.1122143,42.0851107]},"n1820938080":{"id":"n1820938080","loc":[-85.2443785,42.0174567]},"n1820938081":{"id":"n1820938081","loc":[-85.0319733,42.0953853]},"n1820938082":{"id":"n1820938082","loc":[-85.0878276,42.09443]},"n1820938083":{"id":"n1820938083","loc":[-85.0271789,42.0935809]},"n1820938084":{"id":"n1820938084","loc":[-85.0326399,42.0974222]},"n1820938085":{"id":"n1820938085","loc":[-85.3989167,42.0065592]},"n1820938086":{"id":"n1820938086","loc":[-85.3263361,41.9721261]},"n1820938087":{"id":"n1820938087","loc":[-85.2547855,42.0037134]},"n1820938088":{"id":"n1820938088","loc":[-85.4373259,42.005746]},"n1820938089":{"id":"n1820938089","loc":[-85.3094275,41.9699245]},"n1820938090":{"id":"n1820938090","loc":[-85.2783246,41.9872793]},"n1820938092":{"id":"n1820938092","loc":[-85.0815633,42.1025169]},"n1820938093":{"id":"n1820938093","loc":[-85.1788511,42.0522134]},"n1820938095":{"id":"n1820938095","loc":[-85.2830345,41.9816733]},"n1820938096":{"id":"n1820938096","loc":[-85.0744984,42.1059835]},"n1820938097":{"id":"n1820938097","loc":[-85.2788396,41.9879333]},"n1820938098":{"id":"n1820938098","loc":[-85.3640093,41.9946531]},"n1820938099":{"id":"n1820938099","loc":[-85.291167,41.9787463]},"n1820938100":{"id":"n1820938100","loc":[-85.0772436,42.1038156]},"n1820938101":{"id":"n1820938101","loc":[-85.00563,42.0887482]},"n1820938102":{"id":"n1820938102","loc":[-85.0326881,42.0961245]},"n1820938104":{"id":"n1820938104","loc":[-85.0530448,42.1038634]},"n1820938105":{"id":"n1820938105","loc":[-85.2625266,41.9970639]},"n1820938106":{"id":"n1820938106","loc":[-85.2827556,41.9823512]},"n1820938107":{"id":"n1820938107","loc":[-85.2784319,41.9910752]},"n1820938108":{"id":"n1820938108","loc":[-85.0882099,42.094393]},"n1820938109":{"id":"n1820938109","loc":[-85.5718484,41.9645371]},"n1820938110":{"id":"n1820938110","loc":[-85.2559764,42.0099317]},"n1820938111":{"id":"n1820938111","loc":[-85.2969284,41.973179]},"n1820938113":{"id":"n1820938113","loc":[-85.3875055,42.0019726]},"n1820938114":{"id":"n1820938114","loc":[-85.4250779,42.0068199]},"n1820938115":{"id":"n1820938115","loc":[-85.0645367,42.104889]},"n1820938116":{"id":"n1820938116","loc":[-85.1636762,42.0623724]},"n1820938117":{"id":"n1820938117","loc":[-85.0757322,42.1055935]},"n1820938118":{"id":"n1820938118","loc":[-85.3695197,41.9981559]},"n1820938120":{"id":"n1820938120","loc":[-85.1297516,42.0671027]},"n1820938121":{"id":"n1820938121","loc":[-85.1057448,42.0875551]},"n1820938122":{"id":"n1820938122","loc":[-85.2805175,41.9943182]},"n1820938123":{"id":"n1820938123","loc":[-85.2545173,42.0040722]},"n1820938124":{"id":"n1820938124","loc":[-84.9966607,42.0871319]},"n1820938125":{"id":"n1820938125","loc":[-85.0099899,42.0904612]},"n1820938126":{"id":"n1820938126","loc":[-85.2489919,42.0091102]},"n1820938127":{"id":"n1820938127","loc":[-85.0342706,42.0979476]},"n1820938128":{"id":"n1820938128","loc":[-85.1080891,42.0855884]},"n1820938129":{"id":"n1820938129","loc":[-85.0128183,42.0905356]},"n1820938130":{"id":"n1820938130","loc":[-85.631608,41.9434251]},"n1820938131":{"id":"n1820938131","loc":[-85.2551975,42.0008524]},"n1820938132":{"id":"n1820938132","loc":[-85.6421823,41.9096233]},"n1820938133":{"id":"n1820938133","loc":[-85.0125059,42.0906284]},"n1820938134":{"id":"n1820938134","loc":[-85.5499358,41.9701793]},"n1820938135":{"id":"n1820938135","loc":[-85.5472107,41.9712323]},"n1820938136":{"id":"n1820938136","loc":[-85.2760758,41.9958691]},"n1820938137":{"id":"n1820938137","loc":[-85.276678,41.9960433]},"n1820938138":{"id":"n1820938138","loc":[-85.0570319,42.1024731]},"n1820938140":{"id":"n1820938140","loc":[-85.2394325,42.0227492]},"n1820938142":{"id":"n1820938142","loc":[-85.5666341,41.9638829]},"n1820938144":{"id":"n1820938144","loc":[-85.258101,41.9996353]},"n1820938147":{"id":"n1820938147","loc":[-85.2129645,42.0413565]},"n1820938149":{"id":"n1820938149","loc":[-84.9962369,42.0868373]},"n1820938151":{"id":"n1820938151","loc":[-85.2570386,42.0084968]},"n1820938153":{"id":"n1820938153","loc":[-85.3971142,42.0050285]},"n1820938155":{"id":"n1820938155","loc":[-85.1072093,42.0855566]},"n1820938157":{"id":"n1820938157","loc":[-85.2840323,41.9920959]},"n1820938159":{"id":"n1820938159","loc":[-85.1187924,42.0816458]},"n1820938161":{"id":"n1820938161","loc":[-85.2681324,41.9985788]},"n1820938163":{"id":"n1820938163","loc":[-85.0887034,42.0984969]},"n1820938165":{"id":"n1820938165","loc":[-85.4133405,42.0073141]},"n1820938166":{"id":"n1820938166","loc":[-85.0097445,42.0902888]},"n1820938167":{"id":"n1820938167","loc":[-85.0828133,42.1037388]},"n1820938168":{"id":"n1820938168","loc":[-85.0549599,42.1030833]},"n1820938169":{"id":"n1820938169","loc":[-85.4571528,42.0010421]},"n1820938178":{"id":"n1820938178","loc":[-85.2706644,41.9975941]},"n1820938180":{"id":"n1820938180","loc":[-85.2258606,42.0335794]},"n1820938182":{"id":"n1820938182","loc":[-85.2832276,41.9814659]},"n1820938184":{"id":"n1820938184","loc":[-85.1082299,42.0860928]},"n1820938185":{"id":"n1820938185","loc":[-85.3839392,42.0022381]},"n1820938186":{"id":"n1820938186","loc":[-85.2772131,41.995905]},"n1820938187":{"id":"n1820938187","loc":[-85.1044895,42.0879214]},"n1820938188":{"id":"n1820938188","loc":[-85.2135267,42.0407087]},"n1820938189":{"id":"n1820938189","loc":[-85.2543993,42.0044628]},"n1820938190":{"id":"n1820938190","loc":[-85.1501793,42.0617351]},"n1820938191":{"id":"n1820938191","loc":[-85.3350587,41.9820469]},"n1820938192":{"id":"n1820938192","loc":[-85.1350731,42.0655735]},"n1820938193":{"id":"n1820938193","loc":[-85.0404008,42.1028843]},"n1820938194":{"id":"n1820938194","loc":[-85.6323161,41.943042]},"n1820938195":{"id":"n1820938195","loc":[-85.1259593,42.0742837]},"n1820938196":{"id":"n1820938196","loc":[-85.4562988,42.0033758]},"n1820938197":{"id":"n1820938197","loc":[-85.256824,42.0056826]},"n1820938198":{"id":"n1820938198","loc":[-85.2742103,41.9963862]},"n1820938199":{"id":"n1820938199","loc":[-85.0380888,42.1037877]},"n1820938200":{"id":"n1820938200","loc":[-85.47404,41.9944721]},"n1820938201":{"id":"n1820938201","loc":[-85.103021,42.087948]},"n1820938202":{"id":"n1820938202","loc":[-85.4030151,42.0065113]},"n1820938203":{"id":"n1820938203","loc":[-85.2113981,42.040735]},"n1820938204":{"id":"n1820938204","loc":[-85.2603433,41.9965137]},"n1820938206":{"id":"n1820938206","loc":[-85.1669378,42.0607634]},"n1820938207":{"id":"n1820938207","loc":[-85.0642027,42.1046076]},"n1820938208":{"id":"n1820938208","loc":[-85.2812428,41.9915696]},"n1820938209":{"id":"n1820938209","loc":[-85.0839559,42.1038343]},"n1820938210":{"id":"n1820938210","loc":[-85.1239946,42.0769368]},"n1820938211":{"id":"n1820938211","loc":[-85.2311177,42.0283042]},"n1820938212":{"id":"n1820938212","loc":[-85.2791614,41.9882682]},"n1820938213":{"id":"n1820938213","loc":[-85.2674941,41.9987582]},"n1820938214":{"id":"n1820938214","loc":[-85.352787,41.9919579]},"n1820938215":{"id":"n1820938215","loc":[-85.0874146,42.0952182]},"n1820938216":{"id":"n1820938216","loc":[-85.0069711,42.0877092]},"n1820938217":{"id":"n1820938217","loc":[-85.2059049,42.0404004]},"n1820938218":{"id":"n1820938218","loc":[-85.2403552,42.0227332]},"n1820938219":{"id":"n1820938219","loc":[-85.2492923,42.0098915]},"n1820938220":{"id":"n1820938220","loc":[-85.269778,41.9979541]},"n1820938221":{"id":"n1820938221","loc":[-85.2097673,42.0389024]},"n1820938222":{"id":"n1820938222","loc":[-85.0845942,42.1032015]},"n1820938223":{"id":"n1820938223","loc":[-84.993206,42.0858142]},"n1820938224":{"id":"n1820938224","loc":[-85.2108187,42.0402729]},"n1820938225":{"id":"n1820938225","loc":[-84.9893959,42.0873043]},"n1820938226":{"id":"n1820938226","loc":[-85.2952332,41.9719984]},"n1820938227":{"id":"n1820938227","loc":[-85.4100961,42.0081536]},"n1820938228":{"id":"n1820938228","loc":[-85.3299088,41.9785696]},"n1820938229":{"id":"n1820938229","loc":[-85.2258176,42.0340097]},"n1820938230":{"id":"n1820938230","loc":[-85.3146739,41.9711449]},"n1820938231":{"id":"n1820938231","loc":[-85.5447645,41.9712801]},"n1820938232":{"id":"n1820938232","loc":[-85.5510087,41.9705941]},"n1820938233":{"id":"n1820938233","loc":[-85.5122389,41.9703445]},"n1820938234":{"id":"n1820938234","loc":[-85.2792687,41.9865381]},"n1820938235":{"id":"n1820938235","loc":[-85.1475229,42.0630151]},"n1820938237":{"id":"n1820938237","loc":[-85.0332889,42.0996034]},"n1820938238":{"id":"n1820938238","loc":[-85.2588882,41.9986877]},"n1820938239":{"id":"n1820938239","loc":[-85.0656458,42.1050892]},"n1820938240":{"id":"n1820938240","loc":[-84.9913915,42.086098]},"n1820938241":{"id":"n1820938241","loc":[-85.4752416,41.9944402]},"n1820938242":{"id":"n1820938242","loc":[-85.1214304,42.0791147]},"n1820938243":{"id":"n1820938243","loc":[-85.0075183,42.0886925]},"n1820938244":{"id":"n1820938244","loc":[-85.1052888,42.0872087]},"n1820938245":{"id":"n1820938245","loc":[-85.3104252,41.9703393]},"n1820938246":{"id":"n1820938246","loc":[-85.232109,42.0318158]},"n1820938247":{"id":"n1820938247","loc":[-85.0756075,42.1059528]},"n1820938248":{"id":"n1820938248","loc":[-85.0075612,42.0890866]},"n1820938249":{"id":"n1820938249","loc":[-85.1013312,42.0897474]},"n1820938250":{"id":"n1820938250","loc":[-85.1168076,42.0828919]},"n1820938251":{"id":"n1820938251","loc":[-85.2951367,41.9723334]},"n1820938252":{"id":"n1820938252","loc":[-85.0879363,42.0976053]},"n1820938253":{"id":"n1820938253","loc":[-85.0354763,42.1021838]},"n1820938254":{"id":"n1820938254","loc":[-85.2379627,42.0236339]},"n1820938255":{"id":"n1820938255","loc":[-85.1308245,42.0685364]},"n1820938256":{"id":"n1820938256","loc":[-85.0914446,42.0934774]},"n1820938257":{"id":"n1820938257","loc":[-85.2436812,42.014069]},"n1820938258":{"id":"n1820938258","loc":[-85.0682529,42.1056106]},"n1820938259":{"id":"n1820938259","loc":[-85.290652,41.9766805]},"n1820938260":{"id":"n1820938260","loc":[-85.0133494,42.0897434]},"n1820938261":{"id":"n1820938261","loc":[-85.2753047,41.9949429]},"n1820938262":{"id":"n1820938262","loc":[-85.0314691,42.0950788]},"n1820938263":{"id":"n1820938263","loc":[-85.3444786,41.9908359]},"n1820938264":{"id":"n1820938264","loc":[-85.0443115,42.1009061]},"n1820938265":{"id":"n1820938265","loc":[-85.0634853,42.1043159]},"n1820938267":{"id":"n1820938267","loc":[-85.3978223,42.0053952]},"n1820938268":{"id":"n1820938268","loc":[-85.0228659,42.0911885]},"n1820938269":{"id":"n1820938269","loc":[-85.0220237,42.0906272]},"n1820938270":{"id":"n1820938270","loc":[-85.1061525,42.0863369]},"n1820938271":{"id":"n1820938271","loc":[-85.2382309,42.0233708]},"n1820938272":{"id":"n1820938272","loc":[-85.310672,41.9702755]},"n1820938273":{"id":"n1820938273","loc":[-85.1448192,42.0652613]},"n1820938274":{"id":"n1820938274","loc":[-85.6036057,41.9403766]},"n1820938275":{"id":"n1820938275","loc":[-85.0778941,42.1032413]},"n1820938276":{"id":"n1820938276","loc":[-85.1279374,42.0723974]},"n1820938277":{"id":"n1820938277","loc":[-85.2806635,41.9847836]},"n1820938278":{"id":"n1820938278","loc":[-85.2653201,41.9976352]},"n1820938279":{"id":"n1820938279","loc":[-85.0351665,42.1001805]},"n1820938280":{"id":"n1820938280","loc":[-85.0718269,42.1056253]},"n1820938281":{"id":"n1820938281","loc":[-85.2574248,42.0075322]},"n1820938282":{"id":"n1820938282","loc":[-85.126666,42.0740778]},"n1820938283":{"id":"n1820938283","loc":[-85.077705,42.1034733]},"n1820938284":{"id":"n1820938284","loc":[-85.3535552,41.9919045]},"n1820938286":{"id":"n1820938286","loc":[-85.2810711,41.9866657]},"n1820938287":{"id":"n1820938287","loc":[-85.4567494,42.0019885]},"n1820938288":{"id":"n1820938288","loc":[-85.2642419,41.9992936]},"n1820938289":{"id":"n1820938289","loc":[-85.2643344,41.9980925]},"n1820938290":{"id":"n1820938290","loc":[-85.3270335,41.9776125]},"n1820938291":{"id":"n1820938291","loc":[-85.1200584,42.0795077]},"n1820938292":{"id":"n1820938292","loc":[-85.2290792,42.0340256]},"n1820938293":{"id":"n1820938293","loc":[-85.6015887,41.9401372]},"n1820938294":{"id":"n1820938294","loc":[-85.5370869,41.970488]},"n1820938295":{"id":"n1820938295","loc":[-85.3108866,41.9698048]},"n1820938297":{"id":"n1820938297","loc":[-85.1556511,42.0628184]},"n1820938298":{"id":"n1820938298","loc":[-85.0027922,42.0875221]},"n1820938300":{"id":"n1820938300","loc":[-85.3873338,42.0040614]},"n1820938301":{"id":"n1820938301","loc":[-85.0350753,42.1004034]},"n1820938302":{"id":"n1820938302","loc":[-85.6239476,41.9411906]},"n1820938304":{"id":"n1820938304","loc":[-85.0118246,42.0897964]},"n1820938306":{"id":"n1820938306","loc":[-85.4796877,41.995275]},"n1820938307":{"id":"n1820938307","loc":[-85.5388636,41.9707856]},"n1820938309":{"id":"n1820938309","loc":[-85.2971902,41.9727773]},"n1820938310":{"id":"n1820938310","loc":[-85.5426831,41.9715513]},"n1820938311":{"id":"n1820938311","loc":[-85.2798373,41.9836671]},"n1820938312":{"id":"n1820938312","loc":[-85.2432198,42.0104017]},"n1820938313":{"id":"n1820938313","loc":[-85.2650412,41.9987554]},"n1820938317":{"id":"n1820938317","loc":[-85.0015423,42.0882386]},"n1820938318":{"id":"n1820938318","loc":[-85.1409783,42.064879]},"n1820938319":{"id":"n1820938319","loc":[-85.1691908,42.058995]},"n1820938320":{"id":"n1820938320","loc":[-85.1059165,42.0864882]},"n1820938321":{"id":"n1820938321","loc":[-85.3664941,41.9965771]},"n1820938323":{"id":"n1820938323","loc":[-85.3143198,41.9710971]},"n1820938324":{"id":"n1820938324","loc":[-85.0016067,42.0880675]},"n1820938325":{"id":"n1820938325","loc":[-85.0148139,42.0887164]},"n1820938326":{"id":"n1820938326","loc":[-85.0324682,42.0959056]},"n1820938327":{"id":"n1820938327","loc":[-85.0898661,42.0939921]},"n1820938328":{"id":"n1820938328","loc":[-85.2556427,42.0004936]},"n1820938329":{"id":"n1820938329","loc":[-85.6287112,41.9407437]},"n1820938330":{"id":"n1820938330","loc":[-84.9913392,42.0866701]},"n1820938331":{"id":"n1820938331","loc":[-85.2685777,41.9984632]},"n1820938332":{"id":"n1820938332","loc":[-85.0078884,42.0901614]},"n1820938333":{"id":"n1820938333","loc":[-84.999642,42.0878616]},"n1820938334":{"id":"n1820938334","loc":[-85.0188909,42.0899186]},"n1820938335":{"id":"n1820938335","loc":[-85.2830238,41.9819843]},"n1820938336":{"id":"n1820938336","loc":[-85.2491421,42.0096204]},"n1820938337":{"id":"n1820938337","loc":[-85.0585701,42.1034295]},"n1820938338":{"id":"n1820938338","loc":[-85.0651965,42.1051636]},"n1820938339":{"id":"n1820938339","loc":[-85.0583944,42.104292]},"n1820938340":{"id":"n1820938340","loc":[-85.119876,42.0801567]},"n1820938341":{"id":"n1820938341","loc":[-85.0943937,42.0931323]},"n1820938342":{"id":"n1820938342","loc":[-85.1504583,42.0613209]},"n1820938343":{"id":"n1820938343","loc":[-85.0425426,42.1019836]},"n1820938345":{"id":"n1820938345","loc":[-84.9991391,42.0878206]},"n1820938346":{"id":"n1820938346","loc":[-85.2563841,42.0094614]},"n1820938347":{"id":"n1820938347","loc":[-85.0515387,42.103297]},"n1820938348":{"id":"n1820938348","loc":[-85.0857261,42.1003636]},"n1820938349":{"id":"n1820938349","loc":[-85.078971,42.1029241]},"n1820938350":{"id":"n1820938350","loc":[-85.5699558,41.958931]},"n1820938351":{"id":"n1820938351","loc":[-85.3181285,41.9696533]},"n1820938352":{"id":"n1820938352","loc":[-85.5998506,41.9402329]},"n1820938353":{"id":"n1820938353","loc":[-85.2567277,42.000317]},"n1820938354":{"id":"n1820938354","loc":[-85.3082795,41.9708338]},"n1820938355":{"id":"n1820938355","loc":[-85.3127856,41.9692784]},"n1820938356":{"id":"n1820938356","loc":[-85.0340775,42.1010721]},"n1820938357":{"id":"n1820938357","loc":[-85.3158111,41.9706583]},"n1820938359":{"id":"n1820938359","loc":[-85.2312035,42.0280412]},"n1820938360":{"id":"n1820938360","loc":[-85.2448613,42.018477]},"n1820938361":{"id":"n1820938361","loc":[-85.29077,41.9759068]},"n1820938364":{"id":"n1820938364","loc":[-85.3677387,41.9976615]},"n1820938365":{"id":"n1820938365","loc":[-85.0785204,42.1030355]},"n1820938366":{"id":"n1820938366","loc":[-85.2262039,42.0333722]},"n1820938367":{"id":"n1820938367","loc":[-85.1226011,42.0780902]},"n1820938368":{"id":"n1820938368","loc":[-85.3229673,41.971129]},"n1820938369":{"id":"n1820938369","loc":[-85.385334,42.0000056]},"n1820938370":{"id":"n1820938370","loc":[-85.000098,42.0879094]},"n1820938372":{"id":"n1820938372","loc":[-85.3852481,42.0025091]},"n1820938373":{"id":"n1820938373","loc":[-85.3770513,41.9982515]},"n1820938374":{"id":"n1820938374","loc":[-85.6278314,41.9405362]},"n1820938375":{"id":"n1820938375","loc":[-85.6355133,41.9344068]},"n1820938376":{"id":"n1820938376","loc":[-85.635642,41.9324753]},"n1820938377":{"id":"n1820938377","loc":[-85.3154463,41.970778]},"n1820938378":{"id":"n1820938378","loc":[-85.0920334,42.093411]},"n1820938379":{"id":"n1820938379","loc":[-85.3269155,41.9722297]},"n1820938381":{"id":"n1820938381","loc":[-85.1134334,42.0849184]},"n1820938382":{"id":"n1820938382","loc":[-85.005968,42.088585]},"n1820938384":{"id":"n1820938384","loc":[-85.1245203,42.0757183]},"n1820938385":{"id":"n1820938385","loc":[-85.020704,42.0905396]},"n1820938386":{"id":"n1820938386","loc":[-85.119585,42.0808984]},"n1820938387":{"id":"n1820938387","loc":[-85.0072447,42.0880117]},"n1820938388":{"id":"n1820938388","loc":[-85.2742908,41.9960273]},"n1820938389":{"id":"n1820938389","loc":[-85.3275807,41.9696852]},"n1820938390":{"id":"n1820938390","loc":[-85.2385635,42.0231556]},"n1820938392":{"id":"n1820938392","loc":[-85.0202856,42.0900778]},"n1820938393":{"id":"n1820938393","loc":[-85.2067847,42.0395398]},"n1820938394":{"id":"n1820938394","loc":[-85.5183544,41.9713495]},"n1820938396":{"id":"n1820938396","loc":[-85.5073037,41.9736787]},"n1820938397":{"id":"n1820938397","loc":[-85.2519638,42.0114225]},"n1820938398":{"id":"n1820938398","loc":[-85.287487,41.9793285]},"n1820938399":{"id":"n1820938399","loc":[-85.2298088,42.0336431]},"n1820938400":{"id":"n1820938400","loc":[-85.229444,42.0339141]},"n1820938401":{"id":"n1820938401","loc":[-85.2421791,42.0220239]},"n1820938402":{"id":"n1820938402","loc":[-85.2976687,41.9737612]},"n1820938403":{"id":"n1820938403","loc":[-85.3622069,41.993473]},"n1820938404":{"id":"n1820938404","loc":[-85.2465458,42.014906]},"n1820938405":{"id":"n1820938405","loc":[-85.5724663,41.9639412]},"n1820938406":{"id":"n1820938406","loc":[-85.3708501,41.9982037]},"n1820938408":{"id":"n1820938408","loc":[-85.2564592,42.0055311]},"n1820938409":{"id":"n1820938409","loc":[-85.1192846,42.0810856]},"n1820938410":{"id":"n1820938410","loc":[-85.5623812,41.971663]},"n1820938411":{"id":"n1820938411","loc":[-85.3221948,41.9719665]},"n1820938412":{"id":"n1820938412","loc":[-85.5168738,41.9710305]},"n1820938413":{"id":"n1820938413","loc":[-85.4546852,42.0061127]},"n1820938414":{"id":"n1820938414","loc":[-85.5896153,41.9463617]},"n1820938415":{"id":"n1820938415","loc":[-85.2978189,41.9722138]},"n1820938416":{"id":"n1820938416","loc":[-85.1021681,42.0883581]},"n1820938417":{"id":"n1820938417","loc":[-85.2797193,41.9912984]},"n1820938419":{"id":"n1820938419","loc":[-85.2362461,42.0248533]},"n1820938420":{"id":"n1820938420","loc":[-85.4833639,41.9846252]},"n1820938422":{"id":"n1820938422","loc":[-85.3281064,41.9689433]},"n1820938424":{"id":"n1820938424","loc":[-85.2416963,42.0130088]},"n1820938425":{"id":"n1820938425","loc":[-85.5718655,41.9564577]},"n1820938426":{"id":"n1820938426","loc":[-85.0512812,42.1030701]},"n1820938427":{"id":"n1820938427","loc":[-85.1273527,42.0723616]},"n1820938428":{"id":"n1820938428","loc":[-85.0215033,42.0904083]},"n1820938429":{"id":"n1820938429","loc":[-85.6169953,41.942228]},"n1820938430":{"id":"n1820938430","loc":[-85.2829165,41.9907243]},"n1820938431":{"id":"n1820938431","loc":[-85.2240796,42.0374203]},"n1820938432":{"id":"n1820938432","loc":[-85.0167598,42.0898442]},"n1820938433":{"id":"n1820938433","loc":[-85.2132649,42.0411334]},"n1820938434":{"id":"n1820938434","loc":[-85.2293839,42.031513]},"n1820938435":{"id":"n1820938435","loc":[-85.1203374,42.0792608]},"n1820938436":{"id":"n1820938436","loc":[-85.109571,42.086268]},"n1820938437":{"id":"n1820938437","loc":[-85.1079026,42.0853842]},"n1820938438":{"id":"n1820938438","loc":[-85.109237,42.0862413]},"n1820938439":{"id":"n1820938439","loc":[-85.2259936,42.0350831]},"n1820938440":{"id":"n1820938440","loc":[-85.3669705,41.99679]},"n1820938441":{"id":"n1820938441","loc":[-85.2418143,42.0223507]},"n1820938442":{"id":"n1820938442","loc":[-85.3101248,41.9702515]},"n1820938443":{"id":"n1820938443","loc":[-85.069315,42.1059688]},"n1820938444":{"id":"n1820938444","loc":[-85.205862,42.0410378]},"n1820938445":{"id":"n1820938445","loc":[-85.0388076,42.1036604]},"n1820938446":{"id":"n1820938446","loc":[-85.2225389,42.0370115]},"n1820938447":{"id":"n1820938447","loc":[-85.3241474,41.9719346]},"n1820938448":{"id":"n1820938448","loc":[-85.3125496,41.9690789]},"n1820938449":{"id":"n1820938449","loc":[-85.1146497,42.0857039]},"n1820938450":{"id":"n1820938450","loc":[-85.1333944,42.0714963]},"n1820938451":{"id":"n1820938451","loc":[-85.5619306,41.9720937]},"n1820938452":{"id":"n1820938452","loc":[-85.2553651,42.0006479]},"n1820938453":{"id":"n1820938453","loc":[-85.3151137,41.9710093]},"n1820938454":{"id":"n1820938454","loc":[-85.2592315,41.9977947]},"n1820938455":{"id":"n1820938455","loc":[-85.2655723,41.9995966]},"n1820938456":{"id":"n1820938456","loc":[-85.4820652,41.9959233]},"n1820938459":{"id":"n1820938459","loc":[-85.450737,42.0055068]},"n1820938460":{"id":"n1820938460","loc":[-85.2428658,42.0205573]},"n1820938461":{"id":"n1820938461","loc":[-85.0835576,42.1021559]},"n1820938462":{"id":"n1820938462","loc":[-85.244636,42.0194733]},"n1820938463":{"id":"n1820938463","loc":[-85.5702562,41.9581332]},"n1820938465":{"id":"n1820938465","loc":[-85.5680031,41.9659515]},"n1820938467":{"id":"n1820938467","loc":[-85.2798752,41.9948353]},"n1820938468":{"id":"n1820938468","loc":[-85.0477407,42.1015537]},"n1820938469":{"id":"n1820938469","loc":[-85.6403842,41.913732]},"n1820938470":{"id":"n1820938470","loc":[-85.0396029,42.103289]},"n1820938471":{"id":"n1820938471","loc":[-85.2824702,41.9907777]},"n1820938472":{"id":"n1820938472","loc":[-85.2969284,41.9735538]},"n1820938474":{"id":"n1820938474","loc":[-85.401041,42.0070853]},"n1820938475":{"id":"n1820938475","loc":[-85.4116625,42.0073883]},"n1820938476":{"id":"n1820938476","loc":[-85.0437764,42.1016214]},"n1820938477":{"id":"n1820938477","loc":[-85.3643269,41.9958436]},"n1820938478":{"id":"n1820938478","loc":[-85.3895182,42.0009465]},"n1820938479":{"id":"n1820938479","loc":[-85.636157,41.9333373]},"n1820938480":{"id":"n1820938480","loc":[-85.2811355,41.9858044]},"n1820938481":{"id":"n1820938481","loc":[-85.0239052,42.092153]},"n1820938482":{"id":"n1820938482","loc":[-85.2558798,42.0053557]},"n1820938483":{"id":"n1820938483","loc":[-85.2544422,42.0047339]},"n1820938484":{"id":"n1820938484","loc":[-85.4864683,41.9843183]},"n1820938485":{"id":"n1820938485","loc":[-85.2554185,42.0031075]},"n1820938486":{"id":"n1820938486","loc":[-85.3082795,41.9712486]},"n1820938487":{"id":"n1820938487","loc":[-85.2433378,42.0133436]},"n1820938488":{"id":"n1820938488","loc":[-85.0216696,42.0904162]},"n1820938489":{"id":"n1820938489","loc":[-85.2546138,42.0050289]},"n1820938490":{"id":"n1820938490","loc":[-85.2717521,41.9977349]},"n1820938491":{"id":"n1820938491","loc":[-85.0100489,42.0908195]},"n1820938492":{"id":"n1820938492","loc":[-85.207879,42.0392211]},"n1820938493":{"id":"n1820938493","loc":[-85.0007363,42.0882836]},"n1820938494":{"id":"n1820938494","loc":[-85.5775303,41.9504097]},"n1820938495":{"id":"n1820938495","loc":[-85.1131584,42.0847683]},"n1820938496":{"id":"n1820938496","loc":[-85.0887825,42.0941633]},"n1820938497":{"id":"n1820938497","loc":[-85.1185926,42.0818938]},"n1820938498":{"id":"n1820938498","loc":[-85.2748487,41.9948712]},"n1820938499":{"id":"n1820938499","loc":[-85.2566952,42.0090788]},"n1820938500":{"id":"n1820938500","loc":[-85.0774757,42.1036234]},"n1820938501":{"id":"n1820938501","loc":[-85.4190869,42.008903]},"n1820938502":{"id":"n1820938502","loc":[-85.1140395,42.0850577]},"n1820938503":{"id":"n1820938503","loc":[-85.1136104,42.0848627]},"n1820938504":{"id":"n1820938504","loc":[-85.5828089,41.9480638]},"n1820938505":{"id":"n1820938505","loc":[-85.625514,41.9405202]},"n1820938506":{"id":"n1820938506","loc":[-85.2063384,42.0398322]},"n1820938507":{"id":"n1820938507","loc":[-85.3395476,41.9851636]},"n1820938508":{"id":"n1820938508","loc":[-85.0328853,42.0963606]},"n1820938510":{"id":"n1820938510","loc":[-85.1170369,42.0843702]},"n1820938511":{"id":"n1820938511","loc":[-85.2784748,41.9868487]},"n1820938512":{"id":"n1820938512","loc":[-85.6310501,41.9435528]},"n1820938514":{"id":"n1820938514","loc":[-85.0334284,42.0981028]},"n1820938515":{"id":"n1820938515","loc":[-84.9912091,42.0868226]},"n1820938516":{"id":"n1820938516","loc":[-85.2806141,41.9940351]},"n1820938517":{"id":"n1820938517","loc":[-85.1233025,42.0776734]},"n1820938518":{"id":"n1820938518","loc":[-85.2047891,42.0429023]},"n1820938519":{"id":"n1820938519","loc":[-85.1475443,42.0648312]},"n1820938520":{"id":"n1820938520","loc":[-85.2644685,41.9990891]},"n1820938521":{"id":"n1820938521","loc":[-85.1056281,42.0872553]},"n1820938522":{"id":"n1820938522","loc":[-85.4813184,41.9930105]},"n1820938523":{"id":"n1820938523","loc":[-85.321551,41.9722936]},"n1820938524":{"id":"n1820938524","loc":[-85.1564664,42.0631211]},"n1820938525":{"id":"n1820938525","loc":[-85.4149885,42.0079144]},"n1820938527":{"id":"n1820938527","loc":[-85.2861888,41.9803653]},"n1820938528":{"id":"n1820938528","loc":[-85.1301379,42.0682178]},"n1820938529":{"id":"n1820938529","loc":[-85.4156537,42.0084247]},"n1820938530":{"id":"n1820938530","loc":[-85.245151,42.0176082]},"n1820938531":{"id":"n1820938531","loc":[-85.457818,42.0001651]},"n1820938532":{"id":"n1820938532","loc":[-85.310951,41.9694538]},"n1820938533":{"id":"n1820938533","loc":[-85.1509089,42.0611298]},"n1820938534":{"id":"n1820938534","loc":[-85.1108249,42.086321]},"n1820938535":{"id":"n1820938535","loc":[-85.1260344,42.0740687]},"n1820938536":{"id":"n1820938536","loc":[-85.4561228,42.0042791]},"n1820938537":{"id":"n1820938537","loc":[-85.2805082,41.9945761]},"n1820938538":{"id":"n1820938538","loc":[-85.273352,41.9981921]},"n1820938539":{"id":"n1820938539","loc":[-85.1084216,42.0864364]},"n1820938540":{"id":"n1820938540","loc":[-85.5009737,41.9773637]},"n1820938541":{"id":"n1820938541","loc":[-85.3960843,42.0051879]},"n1820938542":{"id":"n1820938542","loc":[-85.3425088,41.9865034]},"n1820938545":{"id":"n1820938545","loc":[-84.9937907,42.0860849]},"n1820938546":{"id":"n1820938546","loc":[-85.1084176,42.086065]},"n1820938547":{"id":"n1820938547","loc":[-85.3492851,41.9924786]},"n1820938548":{"id":"n1820938548","loc":[-85.2512235,42.0101147]},"n1820938549":{"id":"n1820938549","loc":[-85.3717298,41.9979326]},"n1820938551":{"id":"n1820938551","loc":[-85.2573712,42.0064081]},"n1820938552":{"id":"n1820938552","loc":[-85.2514596,42.010139]},"n1820938553":{"id":"n1820938553","loc":[-85.416512,42.0088073]},"n1820938554":{"id":"n1820938554","loc":[-85.4365964,42.0061606]},"n1820938555":{"id":"n1820938555","loc":[-85.4552431,42.0057301]},"n1820938556":{"id":"n1820938556","loc":[-85.2916283,41.9778769]},"n1820938557":{"id":"n1820938557","loc":[-85.100709,42.0902968]},"n1820938558":{"id":"n1820938558","loc":[-85.4703064,41.9965771]},"n1820938559":{"id":"n1820938559","loc":[-85.3134722,41.9696134]},"n1820938560":{"id":"n1820938560","loc":[-85.4834213,41.9885768]},"n1820938561":{"id":"n1820938561","loc":[-85.2740641,41.9975236]},"n1820938562":{"id":"n1820938562","loc":[-85.148334,42.0623405]},"n1820938563":{"id":"n1820938563","loc":[-85.2358598,42.0263675]},"n1820938565":{"id":"n1820938565","loc":[-85.2902979,41.9790892]},"n1820938566":{"id":"n1820938566","loc":[-85.2528865,42.0112869]},"n1820938567":{"id":"n1820938567","loc":[-85.2595319,41.9973003]},"n1820938568":{"id":"n1820938568","loc":[-85.071151,42.105689]},"n1820938570":{"id":"n1820938570","loc":[-85.299278,41.9732188]},"n1820938571":{"id":"n1820938571","loc":[-85.0354669,42.1024771]},"n1820938583":{"id":"n1820938583","loc":[-85.3313937,41.972562]},"n1820938585":{"id":"n1820938585","loc":[-85.0756933,42.1058334]},"n1820938587":{"id":"n1820938587","loc":[-85.3130324,41.9694219]},"n1820938590":{"id":"n1820938590","loc":[-85.0934227,42.0931681]},"n1820938592":{"id":"n1820938592","loc":[-85.3517956,41.9922553]},"n1820938593":{"id":"n1820938593","loc":[-85.4023971,42.0065169]},"n1820938594":{"id":"n1820938594","loc":[-85.3506798,41.9925583]},"n1820938595":{"id":"n1820938595","loc":[-85.3673524,41.9971193]},"n1820938596":{"id":"n1820938596","loc":[-85.1073608,42.0853523]},"n1820938597":{"id":"n1820938597","loc":[-85.2976579,41.972477]},"n1820938598":{"id":"n1820938598","loc":[-85.5616517,41.9694295]},"n1820938599":{"id":"n1820938599","loc":[-85.3552074,41.9921915]},"n1820938600":{"id":"n1820938600","loc":[-85.4665126,41.9999953]},"n1820938601":{"id":"n1820938601","loc":[-85.2740695,41.9966226]},"n1820938602":{"id":"n1820938602","loc":[-85.279376,41.9886669]},"n1820938603":{"id":"n1820938603","loc":[-85.0771109,42.1040413]},"n1820938604":{"id":"n1820938604","loc":[-85.2636049,41.9977895]},"n1820938605":{"id":"n1820938605","loc":[-85.3762145,41.9976456]},"n1820938606":{"id":"n1820938606","loc":[-85.2321369,42.0289577]},"n1820938620":{"id":"n1820938620","loc":[-85.4947724,41.9776189]},"n1820938622":{"id":"n1820938622","loc":[-85.1547069,42.0622768]},"n1820938624":{"id":"n1820938624","loc":[-85.0005056,42.0880249]},"n1820938626":{"id":"n1820938626","loc":[-85.0735596,42.1059357]},"n1820938628":{"id":"n1820938628","loc":[-85.4665298,41.99932]},"n1820938629":{"id":"n1820938629","loc":[-85.434515,42.0065273]},"n1820938630":{"id":"n1820938630","loc":[-85.117462,42.0823823]},"n1820938631":{"id":"n1820938631","loc":[-85.0131777,42.0890707]},"n1820938632":{"id":"n1820938632","loc":[-85.0875326,42.0961934]},"n1820938634":{"id":"n1820938634","loc":[-85.6433839,41.9112042]},"n1820938635":{"id":"n1820938635","loc":[-85.1366181,42.064969]},"n1820938636":{"id":"n1820938636","loc":[-85.073109,42.1057925]},"n1820938638":{"id":"n1820938638","loc":[-85.161406,42.0632541]},"n1820938640":{"id":"n1820938640","loc":[-85.6343932,41.9188845]},"n1820938642":{"id":"n1820938642","loc":[-85.2500004,42.010306]},"n1820938644":{"id":"n1820938644","loc":[-85.291918,41.9753166]},"n1820938663":{"id":"n1820938663","loc":[-85.2841611,41.9916812]},"n1820938664":{"id":"n1820938664","loc":[-85.1052955,42.0868134]},"n1820938665":{"id":"n1820938665","loc":[-85.4606118,42.0005534]},"n1820938666":{"id":"n1820938666","loc":[-85.5672736,41.9642922]},"n1820938667":{"id":"n1820938667","loc":[-85.6348481,41.9316932]},"n1820938668":{"id":"n1820938668","loc":[-85.0224904,42.0909576]},"n1820938669":{"id":"n1820938669","loc":[-85.0133856,42.0899755]},"n1820938670":{"id":"n1820938670","loc":[-85.344779,41.991139]},"n1820938671":{"id":"n1820938671","loc":[-85.632874,41.9425313]},"n1820938673":{"id":"n1820938673","loc":[-85.4941501,41.9779698]},"n1820938675":{"id":"n1820938675","loc":[-85.0862559,42.0997519]},"n1820938676":{"id":"n1820938676","loc":[-85.0097874,42.0898032]},"n1820938678":{"id":"n1820938678","loc":[-84.9913553,42.0863675]},"n1820938680":{"id":"n1820938680","loc":[-85.0533666,42.1038315]},"n1820938682":{"id":"n1820938682","loc":[-85.2950294,41.9743914]},"n1820938684":{"id":"n1820938684","loc":[-85.2517385,42.0104499]},"n1820938686":{"id":"n1820938686","loc":[-85.0247971,42.0922514]},"n1820938688":{"id":"n1820938688","loc":[-85.0807037,42.1026017]},"n1820938690":{"id":"n1820938690","loc":[-85.52462,41.9722748]},"n1820938694":{"id":"n1820938694","loc":[-85.2586535,41.9988818]},"n1820938695":{"id":"n1820938695","loc":[-85.0931612,42.092948]},"n1820938697":{"id":"n1820938697","loc":[-85.2470822,42.016564]},"n1820938698":{"id":"n1820938698","loc":[-85.4143018,42.0075158]},"n1820938699":{"id":"n1820938699","loc":[-85.0771484,42.104487]},"n1820938700":{"id":"n1820938700","loc":[-85.0291208,42.0942775]},"n1820938701":{"id":"n1820938701","loc":[-85.6367964,41.9185971]},"n1820938702":{"id":"n1820938702","loc":[-85.085419,42.1010693]},"n1820938703":{"id":"n1820938703","loc":[-85.0583877,42.1040584]},"n1820938705":{"id":"n1820938705","loc":[-85.2573379,42.0003182]},"n1820938706":{"id":"n1820938706","loc":[-85.2655937,41.9981575]},"n1820938707":{"id":"n1820938707","loc":[-85.023181,42.0915758]},"n1820938708":{"id":"n1820938708","loc":[-85.2318687,42.0274674]},"n1820938709":{"id":"n1820938709","loc":[-85.1056389,42.0866184]},"n1820938710":{"id":"n1820938710","loc":[-85.5276265,41.9700978]},"n1820938711":{"id":"n1820938711","loc":[-85.0864128,42.0945761]},"n1820938712":{"id":"n1820938712","loc":[-84.9897071,42.0871888]},"n1820938714":{"id":"n1820938714","loc":[-85.1328845,42.0665611]},"n1820938715":{"id":"n1820938715","loc":[-85.0336537,42.0991377]},"n1820938716":{"id":"n1820938716","loc":[-85.087597,42.0986692]},"n1820938717":{"id":"n1820938717","loc":[-85.1241394,42.0761882]},"n1820938718":{"id":"n1820938718","loc":[-85.1176002,42.0847723]},"n1820938719":{"id":"n1820938719","loc":[-85.2423615,42.0216572]},"n1820938721":{"id":"n1820938721","loc":[-85.2196378,42.0387908]},"n1820938722":{"id":"n1820938722","loc":[-85.0164272,42.0890082]},"n1820938723":{"id":"n1820938723","loc":[-85.5917182,41.9451807]},"n1820938724":{"id":"n1820938724","loc":[-85.2458806,42.0086638]},"n1820938725":{"id":"n1820938725","loc":[-85.1264474,42.0740527]},"n1820938726":{"id":"n1820938726","loc":[-85.1961631,42.04738]},"n1820938727":{"id":"n1820938727","loc":[-85.2784643,41.9943648]},"n1820938728":{"id":"n1820938728","loc":[-85.2905554,41.9763216]},"n1820938729":{"id":"n1820938729","loc":[-85.2913386,41.9771511]},"n1820938730":{"id":"n1820938730","loc":[-85.0112519,42.0895683]},"n1820938732":{"id":"n1820938732","loc":[-85.4290261,42.0064531]},"n1820938733":{"id":"n1820938733","loc":[-85.3867073,42.0031629]},"n1820938734":{"id":"n1820938734","loc":[-85.4943647,41.9836005]},"n1820938735":{"id":"n1820938735","loc":[-85.4900303,41.9860728]},"n1820938736":{"id":"n1820938736","loc":[-85.0866153,42.0944539]},"n1820938737":{"id":"n1820938737","loc":[-85.0869532,42.0990911]},"n1820938738":{"id":"n1820938738","loc":[-85.6321659,41.9208851]},"n1820938739":{"id":"n1820938739","loc":[-85.5930485,41.9433453]},"n1820938740":{"id":"n1820938740","loc":[-85.0406851,42.102733]},"n1820938741":{"id":"n1820938741","loc":[-85.1051131,42.0869846]},"n1820938742":{"id":"n1820938742","loc":[-85.1377554,42.0648893]},"n1820938743":{"id":"n1820938743","loc":[-85.2795694,41.994604]},"n1820938745":{"id":"n1820938745","loc":[-85.4948153,41.9826594]},"n1820938746":{"id":"n1820938746","loc":[-85.4488916,42.0050923]},"n1820938747":{"id":"n1820938747","loc":[-85.1052526,42.0866144]},"n1820938748":{"id":"n1820938748","loc":[-85.1468749,42.0653991]},"n1820938749":{"id":"n1820938749","loc":[-85.0856886,42.1006104]},"n1820938750":{"id":"n1820938750","loc":[-85.2144022,42.0404004]},"n1820938751":{"id":"n1820938751","loc":[-85.277771,41.9907458]},"n1820938752":{"id":"n1820938752","loc":[-85.1474542,42.0636149]},"n1820938753":{"id":"n1820938753","loc":[-85.0820515,42.1028075]},"n1820938754":{"id":"n1820938754","loc":[-85.1122948,42.08525]},"n1820938756":{"id":"n1820938756","loc":[-85.0173352,42.0901933]},"n1820938757":{"id":"n1820938757","loc":[-85.2259721,42.0354018]},"n1820938758":{"id":"n1820938758","loc":[-85.0872389,42.0987795]},"n1820938759":{"id":"n1820938759","loc":[-85.2291436,42.031874]},"n1820938760":{"id":"n1820938760","loc":[-85.3802485,42.0016002]},"n1820938761":{"id":"n1820938761","loc":[-85.3945822,42.0057938]},"n1820938762":{"id":"n1820938762","loc":[-85.5273237,41.9713017]},"n1820938763":{"id":"n1820938763","loc":[-85.2868862,41.9798629]},"n1820938764":{"id":"n1820938764","loc":[-85.2516677,42.0107899]},"n1820938766":{"id":"n1820938766","loc":[-85.3183002,41.9693103]},"n1820938768":{"id":"n1820938768","loc":[-85.2159042,42.0401932]},"n1820938770":{"id":"n1820938770","loc":[-85.0094481,42.0911141]},"n1820938771":{"id":"n1820938771","loc":[-85.0244538,42.0922155]},"n1820938772":{"id":"n1820938772","loc":[-85.231697,42.028862]},"n1820938773":{"id":"n1820938773","loc":[-85.2102394,42.0390617]},"n1820938774":{"id":"n1820938774","loc":[-85.2463419,42.0151212]},"n1820938775":{"id":"n1820938775","loc":[-85.0726195,42.1056424]},"n1820938776":{"id":"n1820938776","loc":[-85.0060431,42.0883262]},"n1820938778":{"id":"n1820938778","loc":[-85.425889,42.0056982]},"n1820938779":{"id":"n1820938779","loc":[-85.1183042,42.0820638]},"n1820938780":{"id":"n1820938780","loc":[-85.441596,42.0058257]},"n1820938781":{"id":"n1820938781","loc":[-85.1124879,42.0847086]},"n1820938782":{"id":"n1820938782","loc":[-85.2452733,42.0153894]},"n1820938783":{"id":"n1820938783","loc":[-85.2741191,41.9969244]},"n1820938784":{"id":"n1820938784","loc":[-85.2829487,41.9822236]},"n1820938785":{"id":"n1820938785","loc":[-85.3202743,41.972142]},"n1820938786":{"id":"n1820938786","loc":[-85.2345402,42.0266465]},"n1820938787":{"id":"n1820938787","loc":[-85.3037626,41.9724611]},"n1820938789":{"id":"n1820938789","loc":[-85.2474792,42.0161973]},"n1820938790":{"id":"n1820938790","loc":[-85.2951045,41.9727323]},"n1820938791":{"id":"n1820938791","loc":[-85.322345,41.9712726]},"n1820938792":{"id":"n1820938792","loc":[-85.2402372,42.0110394]},"n1820938793":{"id":"n1820938793","loc":[-85.5135693,41.9698659]},"n1820938794":{"id":"n1820938794","loc":[-85.4695339,41.9967366]},"n1820938796":{"id":"n1820938796","loc":[-85.0418492,42.1011131]},"n1820938797":{"id":"n1820938797","loc":[-85.3334107,41.9806337]},"n1820938798":{"id":"n1820938798","loc":[-85.5625314,41.9711685]},"n1820938799":{"id":"n1820938799","loc":[-85.3755707,41.9973585]},"n1820938800":{"id":"n1820938800","loc":[-85.5227532,41.9722429]},"n1820938801":{"id":"n1820938801","loc":[-85.4267687,42.0052836]},"n1820938803":{"id":"n1820938803","loc":[-85.0284704,42.0940837]},"n1820938804":{"id":"n1820938804","loc":[-85.015585,42.0885305]},"n1820938805":{"id":"n1820938805","loc":[-85.0765905,42.1053865]},"n1820938806":{"id":"n1820938806","loc":[-85.2614953,41.9964551]},"n1820938808":{"id":"n1820938808","loc":[-85.0307355,42.0947313]},"n1820938810":{"id":"n1820938810","loc":[-85.3894753,42.0003565]},"n1820938812":{"id":"n1820938812","loc":[-85.0868848,42.095006]},"n1820938813":{"id":"n1820938813","loc":[-85.3854198,42.0009465]},"n1820938814":{"id":"n1820938814","loc":[-85.2659692,41.9993534]},"n1820938815":{"id":"n1820938815","loc":[-85.1234259,42.0765266]},"n1820938816":{"id":"n1820938816","loc":[-85.1426906,42.0648893]},"n1820938818":{"id":"n1820938818","loc":[-85.1014533,42.0893067]},"n1820938819":{"id":"n1820938819","loc":[-85.0883064,42.098067]},"n1820938820":{"id":"n1820938820","loc":[-85.0503156,42.102704]},"n1820938821":{"id":"n1820938821","loc":[-85.1179649,42.0821884]},"n1820938822":{"id":"n1820938822","loc":[-85.3484697,41.9921596]},"n1820938823":{"id":"n1820938823","loc":[-85.3732962,41.9970874]},"n1820938824":{"id":"n1820938824","loc":[-85.2784104,41.9898312]},"n1820938825":{"id":"n1820938825","loc":[-85.4441709,42.0052198]},"n1820938826":{"id":"n1820938826","loc":[-85.3925438,42.0038326]},"n1820938829":{"id":"n1820938829","loc":[-85.5717582,41.9621861]},"n1820938830":{"id":"n1820938830","loc":[-85.0866314,42.0995051]},"n1820938831":{"id":"n1820938831","loc":[-85.576672,41.9522769]},"n1820938832":{"id":"n1820938832","loc":[-85.1587238,42.0636205]},"n1820938833":{"id":"n1820938833","loc":[-85.3804245,41.9999155]},"n1820938834":{"id":"n1820938834","loc":[-85.280083,41.9948843]},"n1820938836":{"id":"n1820938836","loc":[-85.561892,41.9686693]},"n1820938837":{"id":"n1820938837","loc":[-85.0158975,42.0885253]},"n1820938838":{"id":"n1820938838","loc":[-85.4248204,42.007633]},"n1820938839":{"id":"n1820938839","loc":[-85.0352738,42.1039657]},"n1820938840":{"id":"n1820938840","loc":[-85.211956,42.0411812]},"n1820938841":{"id":"n1820938841","loc":[-85.4816575,41.9908997]},"n1820938842":{"id":"n1820938842","loc":[-85.3807635,42.0020308]},"n1820938843":{"id":"n1820938843","loc":[-85.0100865,42.0898521]},"n1820938844":{"id":"n1820938844","loc":[-85.0103936,42.0897434]},"n1820938848":{"id":"n1820938848","loc":[-85.2430052,42.0131363]},"n1820938849":{"id":"n1820938849","loc":[-85.112559,42.0853723]},"n1820938851":{"id":"n1820938851","loc":[-85.3641553,41.9952535]},"n1820938852":{"id":"n1820938852","loc":[-85.2087373,42.0390777]},"n1820938853":{"id":"n1820938853","loc":[-85.2473933,42.0148263]},"n1820938854":{"id":"n1820938854","loc":[-85.0213464,42.090509]},"n1820938855":{"id":"n1820938855","loc":[-85.0673208,42.1052353]},"n1820938856":{"id":"n1820938856","loc":[-85.1003053,42.0905528]},"n1820938857":{"id":"n1820938857","loc":[-85.2617367,41.9965389]},"n1820938858":{"id":"n1820938858","loc":[-85.280363,41.9916015]},"n1820938859":{"id":"n1820938859","loc":[-85.0038866,42.0873469]},"n1820938860":{"id":"n1820938860","loc":[-85.2476401,42.0151451]},"n1820938861":{"id":"n1820938861","loc":[-85.193717,42.0499294]},"n1820938862":{"id":"n1820938862","loc":[-85.3478689,41.9917609]},"n1820938863":{"id":"n1820938863","loc":[-85.5638017,41.9648881]},"n1820938864":{"id":"n1820938864","loc":[-85.4356308,42.0064476]},"n1820938865":{"id":"n1820938865","loc":[-85.0561722,42.1023509]},"n1820938867":{"id":"n1820938867","loc":[-85.2256031,42.0356034]},"n1820938868":{"id":"n1820938868","loc":[-85.6102576,41.9420844]},"n1820938869":{"id":"n1820938869","loc":[-85.2285213,42.0339938]},"n1820938870":{"id":"n1820938870","loc":[-85.0326238,42.0978003]},"n1820938871":{"id":"n1820938871","loc":[-85.0131389,42.0903736]},"n1820938872":{"id":"n1820938872","loc":[-85.2550859,42.0012259]},"n1820938873":{"id":"n1820938873","loc":[-85.1130029,42.0846966]},"n1820938874":{"id":"n1820938874","loc":[-85.1579041,42.06336]},"n1820938875":{"id":"n1820938875","loc":[-85.0430522,42.1020234]},"n1820938876":{"id":"n1820938876","loc":[-85.2786679,41.9865935]},"n1820938877":{"id":"n1820938877","loc":[-85.1221666,42.0788706]},"n1820938878":{"id":"n1820938878","loc":[-85.2554614,42.0103303]},"n1820938879":{"id":"n1820938879","loc":[-85.2349801,42.0265748]},"n1820938880":{"id":"n1820938880","loc":[-85.0997434,42.0907864]},"n1820938881":{"id":"n1820938881","loc":[-85.0045464,42.0878167]},"n1820938882":{"id":"n1820938882","loc":[-85.2728048,41.9982519]},"n1820938883":{"id":"n1820938883","loc":[-85.3111333,41.9691587]},"n1820938884":{"id":"n1820938884","loc":[-85.3219802,41.9721899]},"n1820938885":{"id":"n1820938885","loc":[-85.3091378,41.9699325]},"n1820938887":{"id":"n1820938887","loc":[-85.4242367,42.0085203]},"n1820938888":{"id":"n1820938888","loc":[-84.9968377,42.0874504]},"n1820938890":{"id":"n1820938890","loc":[-85.5443139,41.9714078]},"n1820938891":{"id":"n1820938891","loc":[-85.6404013,41.9154676]},"n1820938892":{"id":"n1820938892","loc":[-85.3644986,41.9962582]},"n1820938893":{"id":"n1820938893","loc":[-85.0496772,42.1018323]},"n1820938894":{"id":"n1820938894","loc":[-85.297261,41.9737373]},"n1820938895":{"id":"n1820938895","loc":[-85.0327096,42.098071]},"n1820938896":{"id":"n1820938896","loc":[-85.3856773,41.9996867]},"n1820938897":{"id":"n1820938897","loc":[-85.0493862,42.1015509]},"n1820938898":{"id":"n1820938898","loc":[-84.9969879,42.0876614]},"n1820938899":{"id":"n1820938899","loc":[-85.0848625,42.1013587]},"n1820938900":{"id":"n1820938900","loc":[-85.5853195,41.9479201]},"n1820938901":{"id":"n1820938901","loc":[-85.6329169,41.9387964]},"n1820938902":{"id":"n1820938902","loc":[-85.0843046,42.1029468]},"n1820938903":{"id":"n1820938903","loc":[-85.1228747,42.0778474]},"n1820938904":{"id":"n1820938904","loc":[-85.4855456,41.984095]},"n1820938905":{"id":"n1820938905","loc":[-85.0573269,42.1026801]},"n1820938906":{"id":"n1820938906","loc":[-85.2425868,42.0131523]},"n1820938907":{"id":"n1820938907","loc":[-85.1149622,42.0860053]},"n1820938908":{"id":"n1820938908","loc":[-85.4833097,41.9951578]},"n1820938909":{"id":"n1820938909","loc":[-85.075979,42.1056372]},"n1820938910":{"id":"n1820938910","loc":[-85.0338509,42.0977139]},"n1820938911":{"id":"n1820938911","loc":[-85.6384272,41.9115715]},"n1820938912":{"id":"n1820938912","loc":[-85.0458363,42.1004074]},"n1820938913":{"id":"n1820938913","loc":[-85.0592138,42.1048305]},"n1820938914":{"id":"n1820938914","loc":[-85.2807493,41.9916653]},"n1820938915":{"id":"n1820938915","loc":[-85.1103274,42.0864193]},"n1820938916":{"id":"n1820938916","loc":[-85.6267156,41.9404404]},"n1820938918":{"id":"n1820938918","loc":[-85.0331374,42.0982911]},"n1820938919":{"id":"n1820938919","loc":[-85.5637331,41.965409]},"n1820938920":{"id":"n1820938920","loc":[-85.5457515,41.9714237]},"n1820938922":{"id":"n1820938922","loc":[-85.082073,42.1030104]},"n1820938923":{"id":"n1820938923","loc":[-85.0780765,42.103102]},"n1820938924":{"id":"n1820938924","loc":[-85.4208035,42.0089508]},"n1820938925":{"id":"n1820938925","loc":[-85.3469934,41.9914795]},"n1820938926":{"id":"n1820938926","loc":[-85.0322,42.095619]},"n1820938927":{"id":"n1820938927","loc":[-85.4784431,41.9949401]},"n1820938928":{"id":"n1820938928","loc":[-85.1303095,42.0667523]},"n1820938929":{"id":"n1820938929","loc":[-85.2463784,42.0084781]},"n1820938930":{"id":"n1820938930","loc":[-85.6299986,41.9427707]},"n1820938931":{"id":"n1820938931","loc":[-85.6325907,41.9238499]},"n1820938932":{"id":"n1820938932","loc":[-85.4808464,41.9914476]},"n1820938934":{"id":"n1820938934","loc":[-85.2411599,42.0105292]},"n1820938935":{"id":"n1820938935","loc":[-85.0163213,42.0892379]},"n1820938936":{"id":"n1820938936","loc":[-85.3290934,41.9682322]},"n1820938937":{"id":"n1820938937","loc":[-85.4925623,41.9853231]},"n1820938938":{"id":"n1820938938","loc":[-85.0338294,42.09892]},"n1820938940":{"id":"n1820938940","loc":[-85.4174561,42.008903]},"n1820938941":{"id":"n1820938941","loc":[-85.1165595,42.0838845]},"n1820938942":{"id":"n1820938942","loc":[-85.2954585,41.9717192]},"n1820938943":{"id":"n1820938943","loc":[-85.6330199,41.9257338]},"n1820938944":{"id":"n1820938944","loc":[-85.2294654,42.0324478]},"n1820938945":{"id":"n1820938945","loc":[-85.5601282,41.9728914]},"n1820938946":{"id":"n1820938946","loc":[-85.1176324,42.08568]},"n1820938947":{"id":"n1820938947","loc":[-85.0210245,42.0906005]},"n1820938948":{"id":"n1820938948","loc":[-85.0251887,42.09253]},"n1820938949":{"id":"n1820938949","loc":[-85.0895832,42.0939551]},"n1820938950":{"id":"n1820938950","loc":[-84.9915109,42.085842]},"n1820938951":{"id":"n1820938951","loc":[-85.2187366,42.0393486]},"n1820938952":{"id":"n1820938952","loc":[-85.006605,42.087579]},"n1820938953":{"id":"n1820938953","loc":[-85.046641,42.1012393]},"n1820938954":{"id":"n1820938954","loc":[-85.052102,42.103695]},"n1820938955":{"id":"n1820938955","loc":[-85.283925,41.9912825]},"n1820938956":{"id":"n1820938956","loc":[-85.2326626,42.0316349]},"n1820938957":{"id":"n1820938957","loc":[-85.1174298,42.0859694]},"n1820938958":{"id":"n1820938958","loc":[-85.3802056,41.9994794]},"n1820938959":{"id":"n1820938959","loc":[-85.4586334,41.9999737]},"n1820938960":{"id":"n1820938960","loc":[-85.4302234,42.0069418]},"n1820938961":{"id":"n1820938961","loc":[-85.092201,42.0930674]},"n1820938962":{"id":"n1820938962","loc":[-85.3684511,41.9979382]},"n1820938963":{"id":"n1820938963","loc":[-85.4618735,42.0011856]},"n1820938964":{"id":"n1820938964","loc":[-85.4828205,41.9877793]},"n1820938965":{"id":"n1820938965","loc":[-85.0837789,42.1025726]},"n1820938966":{"id":"n1820938966","loc":[-85.0176195,42.090253]},"n1820938967":{"id":"n1820938967","loc":[-85.3801627,42.001074]},"n1820938968":{"id":"n1820938968","loc":[-85.4767007,41.994488]},"n1820938969":{"id":"n1820938969","loc":[-85.274268,41.9957495]},"n1820938970":{"id":"n1820938970","loc":[-85.2977438,41.9719506]},"n1820938971":{"id":"n1820938971","loc":[-85.2425546,42.0208682]},"n1820938972":{"id":"n1820938972","loc":[-85.2557082,42.002382]},"n1820938973":{"id":"n1820938973","loc":[-85.3187937,41.9691986]},"n1820938975":{"id":"n1820938975","loc":[-85.2448077,42.0153045]},"n1820938977":{"id":"n1820938977","loc":[-85.0343015,42.0997718]},"n1820938978":{"id":"n1820938978","loc":[-85.2449364,42.01874]},"n1820938979":{"id":"n1820938979","loc":[-85.2598391,41.9969602]},"n1820938980":{"id":"n1820938980","loc":[-85.4294724,42.0067665]},"n1820938981":{"id":"n1820938981","loc":[-85.428082,42.0055124]},"n1820938983":{"id":"n1820938983","loc":[-85.5436315,41.9717484]},"n1820938985":{"id":"n1820938985","loc":[-85.5978336,41.9407437]},"n1820938986":{"id":"n1820938986","loc":[-85.491661,41.9860249]},"n1820938987":{"id":"n1820938987","loc":[-85.4942789,41.9801392]},"n1820938988":{"id":"n1820938988","loc":[-85.0416306,42.1010841]},"n1820938989":{"id":"n1820938989","loc":[-85.2653644,41.9984433]},"n1820938990":{"id":"n1820938990","loc":[-85.1028266,42.0881124]},"n1820938991":{"id":"n1820938991","loc":[-85.0163146,42.0887932]},"n1820938992":{"id":"n1820938992","loc":[-85.5282209,41.9678112]},"n1820938993":{"id":"n1820938993","loc":[-85.5442752,41.9715888]},"n1820938994":{"id":"n1820938994","loc":[-85.5634327,41.9658558]},"n1820938995":{"id":"n1820938995","loc":[-85.0384227,42.1037627]},"n1820938996":{"id":"n1820938996","loc":[-85.1144258,42.0854439]},"n1820938997":{"id":"n1820938997","loc":[-85.1870651,42.0506305]},"n1820938998":{"id":"n1820938998","loc":[-85.1256159,42.0747376]},"n1820938999":{"id":"n1820938999","loc":[-85.3272695,41.9715836]},"n1820939000":{"id":"n1820939000","loc":[-85.0543067,42.103098]},"n1820939001":{"id":"n1820939001","loc":[-85.4678173,41.9973585]},"n1820939003":{"id":"n1820939003","loc":[-85.0266626,42.0933154]},"n1820939004":{"id":"n1820939004","loc":[-85.0353046,42.1019728]},"n1820939005":{"id":"n1820939005","loc":[-85.1237961,42.0762798]},"n1820939006":{"id":"n1820939006","loc":[-85.2812214,41.9826702]},"n1820939007":{"id":"n1820939007","loc":[-85.2927763,41.9747343]},"n1820939008":{"id":"n1820939008","loc":[-85.3270979,41.9720862]},"n1820939009":{"id":"n1820939009","loc":[-85.488657,41.9856581]},"n1820939010":{"id":"n1820939010","loc":[-85.3087301,41.9701399]},"n1820939011":{"id":"n1820939011","loc":[-85.0276939,42.093768]},"n1820939012":{"id":"n1820939012","loc":[-85.2956516,41.9748779]},"n1820939013":{"id":"n1820939013","loc":[-85.1298579,42.0726443]},"n1820939014":{"id":"n1820939014","loc":[-85.105144,42.0870893]},"n1820939015":{"id":"n1820939015","loc":[-85.0677486,42.1053917]},"n1820939016":{"id":"n1820939016","loc":[-85.0333681,42.0993459]},"n1820939017":{"id":"n1820939017","loc":[-85.6384272,41.910805]},"n1820939018":{"id":"n1820939018","loc":[-85.399496,42.006894]},"n1820939019":{"id":"n1820939019","loc":[-85.2648427,41.9998318]},"n1820939020":{"id":"n1820939020","loc":[-85.1237424,42.0766779]},"n1820939021":{"id":"n1820939021","loc":[-85.2515025,42.0109442]},"n1820939022":{"id":"n1820939022","loc":[-85.5566306,41.9718385]},"n1820939023":{"id":"n1820939023","loc":[-85.090644,42.0938369]},"n1820939024":{"id":"n1820939024","loc":[-85.1245525,42.074914]},"n1820939025":{"id":"n1820939025","loc":[-85.1099934,42.0863926]},"n1820939026":{"id":"n1820939026","loc":[-85.1251653,42.0744589]},"n1820939027":{"id":"n1820939027","loc":[-85.401792,42.0068143]},"n1820939028":{"id":"n1820939028","loc":[-85.0094763,42.0899584]},"n1820939029":{"id":"n1820939029","loc":[-85.1330779,42.0705605]},"n1820939030":{"id":"n1820939030","loc":[-85.4935064,41.984398]},"n1820939031":{"id":"n1820939031","loc":[-85.5713334,41.9613939]},"n1820939032":{"id":"n1820939032","loc":[-85.0873945,42.0964669]},"n1820939033":{"id":"n1820939033","loc":[-85.0886497,42.0986481]},"n1820939034":{"id":"n1820939034","loc":[-85.3276343,41.9758897]},"n1820939035":{"id":"n1820939035","loc":[-85.1304386,42.0727387]},"n1820939036":{"id":"n1820939036","loc":[-85.2551932,42.0052999]},"n1820939037":{"id":"n1820939037","loc":[-85.2206936,42.0384458]},"n1820939038":{"id":"n1820939038","loc":[-85.2313645,42.0286389]},"n1820939039":{"id":"n1820939039","loc":[-85.0754586,42.1059835]},"n1820939040":{"id":"n1820939040","loc":[-85.0663324,42.1050812]},"n1820939041":{"id":"n1820939041","loc":[-85.2406234,42.0106887]},"n1820939042":{"id":"n1820939042","loc":[-85.0685962,42.1058175]},"n1820939043":{"id":"n1820939043","loc":[-85.0689462,42.1059437]},"n1820939044":{"id":"n1820939044","loc":[-85.0586144,42.1046144]},"n1820939045":{"id":"n1820939045","loc":[-85.3650565,41.9965452]},"n1820939047":{"id":"n1820939047","loc":[-85.5752558,41.9536014]},"n1820939048":{"id":"n1820939048","loc":[-85.5110159,41.9710624]},"n1820939050":{"id":"n1820939050","loc":[-85.2832641,41.9926477]},"n1820939051":{"id":"n1820939051","loc":[-85.0078402,42.0898947]},"n1820939052":{"id":"n1820939052","loc":[-85.3882737,42.0017916]},"n1820939053":{"id":"n1820939053","loc":[-85.1718945,42.0564937]},"n1820939054":{"id":"n1820939054","loc":[-85.0947048,42.0929293]},"n1820939055":{"id":"n1820939055","loc":[-85.4456944,42.0051082]},"n1820939056":{"id":"n1820939056","loc":[-85.3139872,41.9706903]},"n1820939057":{"id":"n1820939057","loc":[-85.3893895,42.0034021]},"n1820939058":{"id":"n1820939058","loc":[-85.2425332,42.0106089]},"n1820939059":{"id":"n1820939059","loc":[-85.6085624,41.9420844]},"n1820939060":{"id":"n1820939060","loc":[-85.210411,42.0397789]},"n1820939061":{"id":"n1820939061","loc":[-85.2762542,41.9960473]},"n1820939062":{"id":"n1820939062","loc":[-85.4686584,41.9969973]},"n1820939063":{"id":"n1820939063","loc":[-85.3860421,42.0018394]},"n1820939064":{"id":"n1820939064","loc":[-85.5636944,41.9644414]},"n1820939065":{"id":"n1820939065","loc":[-85.3267331,41.9766554]},"n1820939066":{"id":"n1820939066","loc":[-85.0868996,42.0943822]},"n1820939067":{"id":"n1820939067","loc":[-85.104861,42.0880038]},"n1820939068":{"id":"n1820939068","loc":[-85.5537123,41.9695093]},"n1820939069":{"id":"n1820939069","loc":[-85.6325092,41.9396743]},"n1820939070":{"id":"n1820939070","loc":[-85.3869648,42.0024454]},"n1820939071":{"id":"n1820939071","loc":[-85.2775349,41.9957335]},"n1820939072":{"id":"n1820939072","loc":[-85.2055616,42.0421533]},"n1820939073":{"id":"n1820939073","loc":[-85.4731431,41.9946531]},"n1820939074":{"id":"n1820939074","loc":[-85.0399609,42.1030833]},"n1820939075":{"id":"n1820939075","loc":[-85.3055758,41.9725169]},"n1820939076":{"id":"n1820939076","loc":[-85.4834599,41.994488]},"n1820939077":{"id":"n1820939077","loc":[-85.3819866,42.0023018]},"n1820939078":{"id":"n1820939078","loc":[-85.1218756,42.0789992]},"n1820939079":{"id":"n1820939079","loc":[-85.2793159,41.9944458]},"n1820939080":{"id":"n1820939080","loc":[-85.2495498,42.0101466]},"n1820939081":{"id":"n1820939081","loc":[-85.0035969,42.0872434]},"n1820939082":{"id":"n1820939082","loc":[-85.1054243,42.0865626]},"n1820939083":{"id":"n1820939083","loc":[-85.0917665,42.0934774]},"n1820939084":{"id":"n1820939084","loc":[-85.3442211,41.988938]},"n1820939086":{"id":"n1820939086","loc":[-85.273989,41.9953588]},"n1820939087":{"id":"n1820939087","loc":[-85.1142541,42.0852488]},"n1820939089":{"id":"n1820939089","loc":[-85.1526684,42.0615758]},"n1820939090":{"id":"n1820939090","loc":[-85.2538843,42.0110159]},"n1820939091":{"id":"n1820939091","loc":[-85.28341,41.9909635]},"n1820939092":{"id":"n1820939092","loc":[-85.3963178,42.0050217]},"n1820939093":{"id":"n1820939093","loc":[-85.0851682,42.1012472]},"n1820939095":{"id":"n1820939095","loc":[-85.2811784,41.986243]},"n1820939096":{"id":"n1820939096","loc":[-85.4274125,42.0052995]},"n1820939097":{"id":"n1820939097","loc":[-85.0871262,42.0951652]},"n1820939099":{"id":"n1820939099","loc":[-85.1314253,42.0671665]},"n1820939100":{"id":"n1820939100","loc":[-85.2778997,41.991001]},"n1820939101":{"id":"n1820939101","loc":[-85.112107,42.0862812]},"n1820939102":{"id":"n1820939102","loc":[-85.299911,41.9729955]},"n1820939103":{"id":"n1820939103","loc":[-85.639822,41.9094796]},"n1820939104":{"id":"n1820939104","loc":[-85.122294,42.0785334]},"n1820939105":{"id":"n1820939105","loc":[-85.2476294,42.015719]},"n1820939106":{"id":"n1820939106","loc":[-85.4946007,41.9814631]},"n1820939107":{"id":"n1820939107","loc":[-85.0879524,42.0986919]},"n1820939108":{"id":"n1820939108","loc":[-85.0342814,42.098274]},"n1820939109":{"id":"n1820939109","loc":[-85.2450695,42.0095463]},"n1820939110":{"id":"n1820939110","loc":[-85.3847546,42.0024135]},"n1820939111":{"id":"n1820939111","loc":[-85.2961344,41.9742558]},"n1820939112":{"id":"n1820939112","loc":[-85.27899,41.994317]},"n1820939114":{"id":"n1820939114","loc":[-85.1017644,42.0886618]},"n1820939115":{"id":"n1820939115","loc":[-85.076215,42.1056333]},"n1820939116":{"id":"n1820939116","loc":[-85.1198009,42.0805349]},"n1820939117":{"id":"n1820939117","loc":[-85.11988,42.0798513]},"n1820939118":{"id":"n1820939118","loc":[-85.147819,42.0625476]},"n1820939119":{"id":"n1820939119","loc":[-85.0585969,42.1029042]},"n1820939120":{"id":"n1820939120","loc":[-85.1248596,42.0745744]},"n1820939121":{"id":"n1820939121","loc":[-85.3023786,41.9725249]},"n1820939123":{"id":"n1820939123","loc":[-85.0119332,42.0900699]},"n1820939124":{"id":"n1820939124","loc":[-85.2466852,42.0170343]},"n1820939125":{"id":"n1820939125","loc":[-85.0033019,42.0872792]},"n1820939126":{"id":"n1820939126","loc":[-85.0042084,42.0875778]},"n1820939128":{"id":"n1820939128","loc":[-85.0052961,42.0885424]},"n1820939130":{"id":"n1820939130","loc":[-85.0647942,42.10508]},"n1820939131":{"id":"n1820939131","loc":[-85.2824123,41.9825107]},"n1820939132":{"id":"n1820939132","loc":[-85.3210039,41.9723255]},"n1820939133":{"id":"n1820939133","loc":[-85.0491033,42.1014184]},"n1820939134":{"id":"n1820939134","loc":[-85.1127776,42.0855168]},"n1820939135":{"id":"n1820939135","loc":[-85.1243768,42.0759322]},"n1820939137":{"id":"n1820939137","loc":[-85.125974,42.0747547]},"n1820939138":{"id":"n1820939138","loc":[-85.1071248,42.0859973]},"n1820939139":{"id":"n1820939139","loc":[-85.5326175,41.9674833]},"n1820939140":{"id":"n1820939140","loc":[-85.1338715,42.0660833]},"n1820939142":{"id":"n1820939142","loc":[-85.649671,41.9135675]},"n1820939144":{"id":"n1820939144","loc":[-85.0236545,42.0920444]},"n1820939145":{"id":"n1820939145","loc":[-85.1084391,42.0859376]},"n1820939146":{"id":"n1820939146","loc":[-85.1539988,42.0618626]},"n1820939147":{"id":"n1820939147","loc":[-85.2354521,42.026511]},"n1820939148":{"id":"n1820939148","loc":[-85.2362246,42.0260408]},"n1820939149":{"id":"n1820939149","loc":[-85.2401342,42.0115233]},"n1820939150":{"id":"n1820939150","loc":[-85.295319,41.9747423]},"n1820939151":{"id":"n1820939151","loc":[-85.1164696,42.0835409]},"n1820939152":{"id":"n1820939152","loc":[-85.3232891,41.9712885]},"n1820939153":{"id":"n1820939153","loc":[-85.2574463,42.0068944]},"n1820939155":{"id":"n1820939155","loc":[-85.5704064,41.9598246]},"n1820939156":{"id":"n1820939156","loc":[-85.0349077,42.0998116]},"n1820939157":{"id":"n1820939157","loc":[-85.0949529,42.0925619]},"n1820939159":{"id":"n1820939159","loc":[-85.0179829,42.0902343]},"n1820939160":{"id":"n1820939160","loc":[-85.0405832,42.1016942]},"n1820939161":{"id":"n1820939161","loc":[-85.2534015,42.0111833]},"n1820939162":{"id":"n1820939162","loc":[-85.0839881,42.102708]},"n1820939163":{"id":"n1820939163","loc":[-85.0341996,42.1008385]},"n1820939164":{"id":"n1820939164","loc":[-85.1037761,42.0879731]},"n1820939173":{"id":"n1820939173","loc":[-85.0460616,42.1005786]},"n1820939177":{"id":"n1820939177","loc":[-85.0061651,42.0878059]},"n1820939181":{"id":"n1820939181","loc":[-85.1456775,42.0654684]},"n1820939183":{"id":"n1820939183","loc":[-85.1325508,42.0718439]},"n1820939185":{"id":"n1820939185","loc":[-85.2485842,42.008329]},"n1820939187":{"id":"n1820939187","loc":[-85.2744128,41.9949322]},"n1820939189":{"id":"n1820939189","loc":[-85.2579025,41.9999542]},"n1820939191":{"id":"n1820939191","loc":[-85.3358998,41.9828987]},"n1820939193":{"id":"n1820939193","loc":[-85.3192658,41.9716714]},"n1820939194":{"id":"n1820939194","loc":[-85.6400795,41.9130725]},"n1820939195":{"id":"n1820939195","loc":[-85.3278489,41.9780591]},"n1820939196":{"id":"n1820939196","loc":[-85.2800197,41.983061]},"n1820939197":{"id":"n1820939197","loc":[-85.3278167,41.9692943]},"n1820939198":{"id":"n1820939198","loc":[-85.3366894,41.9838653]},"n1820939199":{"id":"n1820939199","loc":[-85.0328383,42.0969923]},"n1820939201":{"id":"n1820939201","loc":[-85.3259284,41.9720383]},"n1820939217":{"id":"n1820939217","loc":[-85.1840181,42.0503277]},"n1820939220":{"id":"n1820939220","loc":[-85.422563,42.0089986]},"n1820939222":{"id":"n1820939222","loc":[-85.555386,41.9707856]},"n1820939224":{"id":"n1820939224","loc":[-85.3830809,42.002254]},"n1820939226":{"id":"n1820939226","loc":[-84.9917938,42.0857517]},"n1820939227":{"id":"n1820939227","loc":[-85.2936775,41.9740484]},"n1820939228":{"id":"n1820939228","loc":[-85.2632133,41.9975024]},"n1820939229":{"id":"n1820939229","loc":[-85.2809424,41.9853259]},"n1820939230":{"id":"n1820939230","loc":[-85.242104,42.0131204]},"n1820939232":{"id":"n1820939232","loc":[-85.2610246,41.9963901]},"n1820939233":{"id":"n1820939233","loc":[-85.2335531,42.0268378]},"n1820939234":{"id":"n1820939234","loc":[-85.3188839,41.9713575]},"n1820939235":{"id":"n1820939235","loc":[-85.2413637,42.0225658]},"n1820939237":{"id":"n1820939237","loc":[-85.0010796,42.0887215]},"n1820939239":{"id":"n1820939239","loc":[-85.2241697,42.0362624]},"n1820939243":{"id":"n1820939243","loc":[-85.0368456,42.1040134]},"n1820939244":{"id":"n1820939244","loc":[-85.1327986,42.069524]},"n1820939260":{"id":"n1820939260","loc":[-85.5408163,41.9711206]},"n1820939261":{"id":"n1820939261","loc":[-85.2959199,41.9746546]},"n1820939262":{"id":"n1820939262","loc":[-85.3298659,41.9683598]},"n1820939263":{"id":"n1820939263","loc":[-85.2240581,42.0358425]},"n1820939264":{"id":"n1820939264","loc":[-85.2438206,42.0101944]},"n1820939265":{"id":"n1820939265","loc":[-85.3984489,42.0059589]},"n1820939266":{"id":"n1820939266","loc":[-85.2330811,42.0294279]},"n1820939268":{"id":"n1820939268","loc":[-85.1126877,42.0857704]},"n1820939271":{"id":"n1820939271","loc":[-85.254925,42.0106253]},"n1820939273":{"id":"n1820939273","loc":[-85.4328046,42.0064662]},"n1820939277":{"id":"n1820939277","loc":[-85.289622,41.9789616]},"n1820939279":{"id":"n1820939279","loc":[-85.4574532,42.0004043]},"n1820939281":{"id":"n1820939281","loc":[-85.4803486,41.9867211]},"n1820939283":{"id":"n1820939283","loc":[-85.157475,42.0631848]},"n1820939285":{"id":"n1820939285","loc":[-85.2571458,42.0059935]},"n1820939287":{"id":"n1820939287","loc":[-85.2818544,41.9825984]},"n1820939289":{"id":"n1820939289","loc":[-85.2298302,42.0328781]},"n1820939291":{"id":"n1820939291","loc":[-85.4819523,41.984821]},"n1820939301":{"id":"n1820939301","loc":[-85.3139765,41.9701159]},"n1820939304":{"id":"n1820939304","loc":[-85.0424447,42.101742]},"n1820939306":{"id":"n1820939306","loc":[-85.6360283,41.9338482]},"n1820939310":{"id":"n1820939310","loc":[-85.3463025,41.9913622]},"n1820939312":{"id":"n1820939312","loc":[-85.4664869,41.9988097]},"n1820939314":{"id":"n1820939314","loc":[-85.149364,42.0622449]},"n1820939316":{"id":"n1820939316","loc":[-85.2460415,42.0153125]},"n1820939318":{"id":"n1820939318","loc":[-85.4806103,41.9924523]},"n1820939320":{"id":"n1820939320","loc":[-85.2449042,42.0190987]},"n1820939322":{"id":"n1820939322","loc":[-85.5280165,41.9689263]},"n1820939324":{"id":"n1820939324","loc":[-85.0051204,42.0882625]},"n1820939326":{"id":"n1820939326","loc":[-85.1240925,42.0771546]},"n1820939329":{"id":"n1820939329","loc":[-85.2261653,42.0342225]},"n1820939331":{"id":"n1820939331","loc":[-85.5259933,41.972211]},"n1820939333":{"id":"n1820939333","loc":[-85.0074754,42.0883183]},"n1820939335":{"id":"n1820939335","loc":[-85.0764014,42.1055549]},"n1820939336":{"id":"n1820939336","loc":[-85.2908773,41.9769597]},"n1820939337":{"id":"n1820939337","loc":[-85.4095382,42.0083449]},"n1820939346":{"id":"n1820939346","loc":[-85.2514166,42.0111753]},"n1820939348":{"id":"n1820939348","loc":[-85.0030377,42.0873799]},"n1820939350":{"id":"n1820939350","loc":[-85.3659362,41.9964974]},"n1820939352":{"id":"n1820939352","loc":[-85.226058,42.0348281]},"n1820939355":{"id":"n1820939355","loc":[-85.1902408,42.0507101]},"n1820939357":{"id":"n1820939357","loc":[-85.2781854,41.9946001]},"n1820939359":{"id":"n1820939359","loc":[-85.2139988,42.0405175]},"n1820939361":{"id":"n1820939361","loc":[-85.0086609,42.0908262]},"n1820939363":{"id":"n1820939363","loc":[-85.0627128,42.1043398]},"n1820939365":{"id":"n1820939365","loc":[-85.1311346,42.072501]},"n1820939369":{"id":"n1820939369","loc":[-85.248198,42.0082652]},"n1820939370":{"id":"n1820939370","loc":[-84.99792,42.087794]},"n1820939371":{"id":"n1820939371","loc":[-85.2786775,41.9942783]},"n1820939372":{"id":"n1820939372","loc":[-85.0342103,42.1013957]},"n1820939373":{"id":"n1820939373","loc":[-85.2022357,42.0444799]},"n1820939374":{"id":"n1820939374","loc":[-85.2279205,42.0337388]},"n1820939375":{"id":"n1820939375","loc":[-85.1337699,42.0712614]},"n1820939376":{"id":"n1820939376","loc":[-85.317517,41.9707062]},"n1820939377":{"id":"n1820939377","loc":[-85.1326326,42.070218]},"n1820939394":{"id":"n1820939394","loc":[-85.0197746,42.0899118]},"n1820939397":{"id":"n1820939397","loc":[-85.2590076,41.9984632]},"n1820939399":{"id":"n1820939399","loc":[-85.2469964,42.0083449]},"n1820939400":{"id":"n1820939400","loc":[-85.2470929,42.0146668]},"n1820939401":{"id":"n1820939401","loc":[-84.9984095,42.0878087]},"n1820939402":{"id":"n1820939402","loc":[-85.2372653,42.0243273]},"n1820939403":{"id":"n1820939403","loc":[-85.2454986,42.0091955]},"n1820939404":{"id":"n1820939404","loc":[-85.0539205,42.1035995]},"n1820939405":{"id":"n1820939405","loc":[-85.550601,41.9706101]},"n1820939406":{"id":"n1820939406","loc":[-85.0351343,42.0999656]},"n1820939407":{"id":"n1820939407","loc":[-85.0082908,42.0905755]},"n1820939408":{"id":"n1820939408","loc":[-85.0132904,42.0902251]},"n1820939410":{"id":"n1820939410","loc":[-85.0892546,42.094012]},"n1820939412":{"id":"n1820939412","loc":[-85.0350793,42.1030315]},"n1820939416":{"id":"n1820939416","loc":[-85.0012406,42.0886777]},"n1820939418":{"id":"n1820939418","loc":[-85.0577453,42.1029229]},"n1820939420":{"id":"n1820939420","loc":[-85.1230786,42.0776722]},"n1820939422":{"id":"n1820939422","loc":[-85.571136,41.9649304]},"n1820939436":{"id":"n1820939436","loc":[-85.1137968,42.0848997]},"n1820939437":{"id":"n1820939437","loc":[-85.3559584,41.9925105]},"n1820939438":{"id":"n1820939438","loc":[-85.0080172,42.0903565]},"n1820939439":{"id":"n1820939439","loc":[-85.0048897,42.0880913]},"n1820939441":{"id":"n1820939441","loc":[-85.0406959,42.1018574]},"n1820939443":{"id":"n1820939443","loc":[-85.3897328,42.0029078]},"n1820939445":{"id":"n1820939445","loc":[-85.122349,42.0782814]},"n1820939448":{"id":"n1820939448","loc":[-85.4872193,41.985036]},"n1820939450":{"id":"n1820939450","loc":[-85.0120459,42.0904919]},"n1820939452":{"id":"n1820939452","loc":[-85.6320543,41.921982]},"n1820939456":{"id":"n1820939456","loc":[-85.0844749,42.1036843]},"n1820939458":{"id":"n1820939458","loc":[-85.0968037,42.091296]},"n1820939463":{"id":"n1820939463","loc":[-85.5339747,41.9681841]},"n1820939465":{"id":"n1820939465","loc":[-85.4125423,42.0072129]},"n1820939467":{"id":"n1820939467","loc":[-85.6335563,41.9303626]},"n1820939469":{"id":"n1820939469","loc":[-85.2821014,41.9932126]},"n1820939471":{"id":"n1820939471","loc":[-85.374691,41.9969917]},"n1820939485":{"id":"n1820939485","loc":[-85.4471321,42.0049806]},"n1820939487":{"id":"n1820939487","loc":[-85.3752532,41.9972206]},"n1820939489":{"id":"n1820939489","loc":[-85.4517283,42.005927]},"n1820939492":{"id":"n1820939492","loc":[-85.4662552,42.0005693]},"n1820939494":{"id":"n1820939494","loc":[-85.0120083,42.0902928]},"n1820939496":{"id":"n1820939496","loc":[-85.044463,42.1004631]},"n1820939498":{"id":"n1820939498","loc":[-85.418293,42.0089667]},"n1820939500":{"id":"n1820939500","loc":[-85.0554762,42.1027358]},"n1820939504":{"id":"n1820939504","loc":[-85.1246289,42.0746858]},"n1820939507":{"id":"n1820939507","loc":[-85.0408139,42.1021838]},"n1820939508":{"id":"n1820939508","loc":[-85.1236204,42.0775169]},"n1820939509":{"id":"n1820939509","loc":[-85.0350109,42.1037428]},"n1820939510":{"id":"n1820939510","loc":[-85.0551583,42.1029878]},"n1820939511":{"id":"n1820939511","loc":[-85.0956771,42.0916662]},"n1820939512":{"id":"n1820939512","loc":[-85.2323408,42.0273638]},"n1820939513":{"id":"n1820939513","loc":[-85.1232771,42.0762388]},"n1820939531":{"id":"n1820939531","loc":[-85.264608,41.9997828]},"n1820939533":{"id":"n1820939533","loc":[-85.4198808,42.0087914]},"n1820939535":{"id":"n1820939535","loc":[-85.3080864,41.9715677]},"n1820939536":{"id":"n1820939536","loc":[-85.1189426,42.0812596]},"n1820939537":{"id":"n1820939537","loc":[-85.2642741,41.9996764]},"n1820939538":{"id":"n1820939538","loc":[-85.2572531,42.0079627]},"n1820939539":{"id":"n1820939539","loc":[-85.2907807,41.9790174]},"n1820939540":{"id":"n1820939540","loc":[-85.3171415,41.9707301]},"n1820939541":{"id":"n1820939541","loc":[-85.08777,42.0953841]},"n1820939542":{"id":"n1820939542","loc":[-85.1239262,42.0773218]},"n1820939543":{"id":"n1820939543","loc":[-84.9973956,42.0877968]},"n1820939544":{"id":"n1820939544","loc":[-85.011606,42.0896161]},"n1820939545":{"id":"n1820939545","loc":[-85.4077358,42.0082971]},"n1820939546":{"id":"n1820939546","loc":[-85.3614945,41.9933717]},"n1820939547":{"id":"n1820939547","loc":[-85.3189118,41.9697649]},"n1820939550":{"id":"n1820939550","loc":[-85.1262691,42.0740221]},"n1820939551":{"id":"n1820939551","loc":[-85.3863639,41.9994635]},"n1820939552":{"id":"n1820939552","loc":[-85.2836034,41.9923953]},"n1820939554":{"id":"n1820939554","loc":[-85.3222377,41.9715916]},"n1820939555":{"id":"n1820939555","loc":[-85.0122658,42.0906312]},"n1820939556":{"id":"n1820939556","loc":[-85.0022652,42.0877581]},"n1820939557":{"id":"n1820939557","loc":[-85.1011314,42.0899954]},"n1820939559":{"id":"n1820939559","loc":[-85.0008181,42.0885293]},"n1820939561":{"id":"n1820939561","loc":[-85.3637046,41.9942488]},"n1820939562":{"id":"n1820939562","loc":[-85.4500117,42.0052892]},"n1820939563":{"id":"n1820939563","loc":[-85.0537636,42.1036365]},"n1820939565":{"id":"n1820939565","loc":[-85.2367503,42.0246939]},"n1820939566":{"id":"n1820939566","loc":[-85.0448479,42.1002653]},"n1820939567":{"id":"n1820939567","loc":[-85.6337065,41.9295006]},"n1820939568":{"id":"n1820939568","loc":[-85.0879792,42.095623]},"n1820939569":{"id":"n1820939569","loc":[-85.6347623,41.9352369]},"n1820939570":{"id":"n1820939570","loc":[-85.1497931,42.0620378]},"n1820939571":{"id":"n1820939571","loc":[-85.5676169,41.9656324]},"n1820939572":{"id":"n1820939572","loc":[-85.638041,41.9166971]},"n1820939573":{"id":"n1820939573","loc":[-85.4993429,41.9781293]},"n1820939574":{"id":"n1820939574","loc":[-85.5352831,41.9692127]},"n1820939575":{"id":"n1820939575","loc":[-84.9924429,42.0857118]},"n1820939577":{"id":"n1820939577","loc":[-85.0581101,42.1026721]},"n1820939578":{"id":"n1820939578","loc":[-85.641088,41.9094477]},"n1820939579":{"id":"n1820939579","loc":[-85.2548821,42.0052282]},"n1820939580":{"id":"n1820939580","loc":[-85.1124463,42.0859734]},"n1820939581":{"id":"n1820939581","loc":[-85.1083479,42.0857624]},"n1820939583":{"id":"n1820939583","loc":[-85.1387424,42.0648893]},"n1820939584":{"id":"n1820939584","loc":[-85.5152645,41.9700892]},"n1820939585":{"id":"n1820939585","loc":[-85.5463738,41.9713439]},"n1820939586":{"id":"n1820939586","loc":[-85.360207,41.9933717]},"n1820939587":{"id":"n1820939587","loc":[-85.2402372,42.0120917]},"n1820939588":{"id":"n1820939588","loc":[-85.3936381,42.0047255]},"n1820939589":{"id":"n1820939589","loc":[-85.3310246,41.973784]},"n1820939590":{"id":"n1820939590","loc":[-85.0329403,42.096642]},"n1820939591":{"id":"n1820939591","loc":[-85.0097271,42.0910981]},"n1820939593":{"id":"n1820939593","loc":[-85.0446562,42.1003437]},"n1820939595":{"id":"n1820939595","loc":[-85.0856671,42.1008452]},"n1820939596":{"id":"n1820939596","loc":[-85.4087228,42.0083449]},"n1820939597":{"id":"n1820939597","loc":[-85.0609519,42.1052564]},"n1820939598":{"id":"n1820939598","loc":[-85.3432126,41.9874548]},"n1820939599":{"id":"n1820939599","loc":[-85.4041738,42.0067027]},"n1820939600":{"id":"n1820939600","loc":[-85.0825437,42.1035768]},"n1820939601":{"id":"n1820939601","loc":[-85.048422,42.101498]},"n1820939602":{"id":"n1820939602","loc":[-85.0336256,42.0999031]},"n1820939603":{"id":"n1820939603","loc":[-85.046818,42.1014104]},"n1820939605":{"id":"n1820939605","loc":[-85.2856524,41.98078]},"n1820939607":{"id":"n1820939607","loc":[-85.1118173,42.0864245]},"n1820939609":{"id":"n1820939609","loc":[-85.0443397,42.1006263]},"n1820939610":{"id":"n1820939610","loc":[-85.0336698,42.0978361]},"n1820939611":{"id":"n1820939611","loc":[-85.4630322,42.0014248]},"n1820939612":{"id":"n1820939612","loc":[-85.0613127,42.1052353]},"n1820939613":{"id":"n1820939613","loc":[-85.0137571,42.0887801]},"n1820939614":{"id":"n1820939614","loc":[-85.272487,41.9982013]},"n1820939616":{"id":"n1820939616","loc":[-85.4665727,41.9983791]},"n1820939617":{"id":"n1820939617","loc":[-85.1288078,42.0725476]},"n1820939618":{"id":"n1820939618","loc":[-85.4653282,42.00109]},"n1820939619":{"id":"n1820939619","loc":[-85.2314717,42.0276746]},"n1820939620":{"id":"n1820939620","loc":[-85.255982,42.0003569]},"n1820939621":{"id":"n1820939621","loc":[-85.2886779,41.9787223]},"n1820939622":{"id":"n1820939622","loc":[-85.22438,42.0367509]},"n1820939623":{"id":"n1820939623","loc":[-85.0334713,42.0998382]},"n1820939624":{"id":"n1820939624","loc":[-85.2236504,42.037484]},"n1820939625":{"id":"n1820939625","loc":[-85.636908,41.9175162]},"n1820939627":{"id":"n1820939627","loc":[-85.2669187,41.9989707]},"n1820939628":{"id":"n1820939628","loc":[-85.3247268,41.9720702]},"n1820939629":{"id":"n1820939629","loc":[-85.3785104,41.9987299]},"n1820939630":{"id":"n1820939630","loc":[-85.5267658,41.9720515]},"n1820939631":{"id":"n1820939631","loc":[-85.2445116,42.0098811]},"n1820939632":{"id":"n1820939632","loc":[-85.1271448,42.0725077]},"n1820939633":{"id":"n1820939633","loc":[-85.0345751,42.099724]},"n1820939634":{"id":"n1820939634","loc":[-85.4217476,42.0089986]},"n1820939635":{"id":"n1820939635","loc":[-85.3121848,41.9689433]},"n1820939636":{"id":"n1820939636","loc":[-85.2826419,41.9929985]},"n1820939637":{"id":"n1820939637","loc":[-85.3160257,41.9706344]},"n1820939638":{"id":"n1820939638","loc":[-85.5684967,41.9657919]},"n1820939640":{"id":"n1820939640","loc":[-85.225131,42.0356194]},"n1820939642":{"id":"n1820939642","loc":[-85.1324124,42.0693328]},"n1820939644":{"id":"n1820939644","loc":[-84.9994073,42.0878843]},"n1820939645":{"id":"n1820939645","loc":[-85.1087596,42.0863329]},"n1820939646":{"id":"n1820939646","loc":[-85.2915532,41.9782996]},"n1820939647":{"id":"n1820939647","loc":[-84.9988708,42.0877808]},"n1820939648":{"id":"n1820939648","loc":[-85.2243628,42.0356728]},"n1820939649":{"id":"n1820939649","loc":[-85.0427397,42.1020524]},"n1820939650":{"id":"n1820939650","loc":[-85.6388392,41.9100752]},"n1820939651":{"id":"n1820939651","loc":[-85.0133709,42.0888557]},"n1820939652":{"id":"n1820939652","loc":[-85.318798,41.9701211]},"n1820939653":{"id":"n1820939653","loc":[-85.6335778,41.9190602]},"n1820939654":{"id":"n1820939654","loc":[-85.6338396,41.9370247]},"n1820939655":{"id":"n1820939655","loc":[-85.0939069,42.0931988]},"n1820939656":{"id":"n1820939656","loc":[-85.5702347,41.9651378]},"n1820939657":{"id":"n1820939657","loc":[-85.4235286,42.0088392]},"n1820939658":{"id":"n1820939658","loc":[-85.2740856,41.9972206]},"n1820939659":{"id":"n1820939659","loc":[-85.4824299,41.9934195]},"n1820939660":{"id":"n1820939660","loc":[-85.3857846,42.0014408]},"n1820939661":{"id":"n1820939661","loc":[-85.0451658,42.10028]},"n1820939662":{"id":"n1820939662","loc":[-85.3893036,42.001377]},"n1820939664":{"id":"n1820939664","loc":[-85.2455845,42.0088607]},"n1820939665":{"id":"n1820939665","loc":[-85.2741071,41.9951116]},"n1820939666":{"id":"n1820939666","loc":[-85.1298375,42.0677718]},"n1820939667":{"id":"n1820939667","loc":[-85.5491848,41.9707377]},"n1820939669":{"id":"n1820939669","loc":[-85.2780298,41.995238]},"n1820939670":{"id":"n1820939670","loc":[-85.1330068,42.0716926]},"n1820939671":{"id":"n1820939671","loc":[-85.0811342,42.1025129]},"n1820939672":{"id":"n1820939672","loc":[-85.2325124,42.0290135]},"n1820939673":{"id":"n1820939673","loc":[-85.2975077,41.9716953]},"n1820939674":{"id":"n1820939674","loc":[-85.0951729,42.0922394]},"n1820939676":{"id":"n1820939676","loc":[-85.0363252,42.1043119]},"n1820939677":{"id":"n1820939677","loc":[-85.2960057,41.97349]},"n1820939678":{"id":"n1820939678","loc":[-85.3701849,41.9982515]},"n1820939679":{"id":"n1820939679","loc":[-85.3381486,41.9848861]},"n1820939680":{"id":"n1820939680","loc":[-85.2058448,42.0417286]},"n1820939682":{"id":"n1820939682","loc":[-85.0819335,42.1034443]},"n1820939683":{"id":"n1820939683","loc":[-85.3872223,41.9993359]},"n1820939684":{"id":"n1820939684","loc":[-85.095366,42.091909]},"n1820939685":{"id":"n1820939685","loc":[-85.2327914,42.0291888]},"n1820939686":{"id":"n1820939686","loc":[-85.0433459,42.1018773]},"n1820939687":{"id":"n1820939687","loc":[-85.0585339,42.1027318]},"n1820939688":{"id":"n1820939688","loc":[-85.0062885,42.0876347]},"n1820939689":{"id":"n1820939689","loc":[-85.246299,42.017377]},"n1820939690":{"id":"n1820939690","loc":[-85.2932376,41.9742877]},"n1820939691":{"id":"n1820939691","loc":[-85.2962846,41.9736815]},"n1820939692":{"id":"n1820939692","loc":[-85.6052365,41.9409193]},"n1820939693":{"id":"n1820939693","loc":[-85.2570536,42.0003341]},"n1820939694":{"id":"n1820939694","loc":[-85.0488458,42.1014064]},"n1820939695":{"id":"n1820939695","loc":[-85.4050321,42.0069578]},"n1820939696":{"id":"n1820939696","loc":[-85.4847517,41.9845894]},"n1820939697":{"id":"n1820939697","loc":[-85.0844655,42.1013826]},"n1820939698":{"id":"n1820939698","loc":[-85.1437206,42.0650008]},"n1820939699":{"id":"n1820939699","loc":[-85.1168183,42.0864034]},"n1820939700":{"id":"n1820939700","loc":[-85.5479831,41.9711366]},"n1820939701":{"id":"n1820939701","loc":[-85.0349948,42.1034124]},"n1820939702":{"id":"n1820939702","loc":[-85.0835589,42.1038821]},"n1820939703":{"id":"n1820939703","loc":[-85.0203875,42.0902649]},"n1820939704":{"id":"n1820939704","loc":[-85.0371191,42.1038184]},"n1820939705":{"id":"n1820939705","loc":[-85.1273312,42.0735681]},"n1820939707":{"id":"n1820939707","loc":[-85.1272239,42.0730226]},"n1820939710":{"id":"n1820939710","loc":[-85.0349881,42.1019012]},"n1820939712":{"id":"n1820939712","loc":[-85.2440459,42.0178313]},"n1820939713":{"id":"n1820939713","loc":[-85.2444751,42.0182618]},"n1820939714":{"id":"n1820939714","loc":[-85.0539996,42.1032863]},"n1820939715":{"id":"n1820939715","loc":[-85.2215905,42.0373246]},"n1820939716":{"id":"n1820939716","loc":[-85.0649712,42.1051994]},"n1820939717":{"id":"n1820939717","loc":[-85.0927146,42.0927581]},"n1820939718":{"id":"n1820939718","loc":[-85.3884668,42.0042312]},"n1820939719":{"id":"n1820939719","loc":[-85.0840672,42.1013241]},"n1820939720":{"id":"n1820939720","loc":[-85.304739,41.9725408]},"n1820939721":{"id":"n1820939721","loc":[-85.2243585,42.0371334]},"n1820939722":{"id":"n1820939722","loc":[-85.0599823,42.1049686]},"n1820939723":{"id":"n1820939723","loc":[-85.0298825,42.0944288]},"n1820939724":{"id":"n1820939724","loc":[-85.0366095,42.1042443]},"n1820939725":{"id":"n1820939725","loc":[-85.0698783,42.1058135]},"n1820939726":{"id":"n1820939726","loc":[-85.1054551,42.0873361]},"n1820939727":{"id":"n1820939727","loc":[-84.9952324,42.0864285]},"n1820939728":{"id":"n1820939728","loc":[-85.3442211,41.9897993]},"n1820939729":{"id":"n1820939729","loc":[-85.4386134,42.0056822]},"n1820939730":{"id":"n1820939730","loc":[-85.2438528,42.0146589]},"n1820939731":{"id":"n1820939731","loc":[-85.0355581,42.1041846]},"n1820939732":{"id":"n1820939732","loc":[-85.557682,41.9724447]},"n1820939734":{"id":"n1820939734","loc":[-85.2299418,42.033314]},"n1820939735":{"id":"n1820939735","loc":[-85.6297412,41.9419088]},"n1820939736":{"id":"n1820939736","loc":[-85.2645101,41.9980259]},"n1820939738":{"id":"n1820939738","loc":[-85.082195,42.1035649]},"n1820939739":{"id":"n1820939739","loc":[-85.234272,42.0267102]},"n1820939740":{"id":"n1820939740","loc":[-85.0130758,42.0895006]},"n1820939741":{"id":"n1820939741","loc":[-85.4594702,42.0000375]},"n1820939742":{"id":"n1820939742","loc":[-84.9946745,42.0863687]},"n1820939743":{"id":"n1820939743","loc":[-85.6438775,41.9120186]},"n1820939744":{"id":"n1820939744","loc":[-85.6372685,41.9168089]},"n1820939745":{"id":"n1820939745","loc":[-85.2789468,41.9893208]},"n1820939747":{"id":"n1820939747","loc":[-85.3775019,41.998427]},"n1820939749":{"id":"n1820939749","loc":[-85.0993571,42.0909178]},"n1820939750":{"id":"n1820939750","loc":[-85.1308503,42.0669339]},"n1820939751":{"id":"n1820939751","loc":[-85.4802566,41.9856659]},"n1820939752":{"id":"n1820939752","loc":[-85.2543563,42.0108804]},"n1820939753":{"id":"n1820939753","loc":[-85.1041033,42.0878815]},"n1820939755":{"id":"n1820939755","loc":[-85.4000969,42.0071651]},"n1820939757":{"id":"n1820939757","loc":[-85.3858275,42.0022381]},"n1820939758":{"id":"n1820939758","loc":[-85.3653998,41.996609]},"n1820939759":{"id":"n1820939759","loc":[-85.2432949,42.0202305]},"n1820939760":{"id":"n1820939760","loc":[-85.3878874,42.0042472]},"n1820939761":{"id":"n1820939761","loc":[-85.2516741,42.0114145]},"n1820939762":{"id":"n1820939762","loc":[-85.2788825,41.9865142]},"n1820939763":{"id":"n1820939763","loc":[-85.0009147,42.0886686]},"n1820939764":{"id":"n1820939764","loc":[-85.3918142,42.003434]},"n1820939765":{"id":"n1820939765","loc":[-85.5532832,41.9696848]},"n1820939766":{"id":"n1820939766","loc":[-85.5545063,41.969254]},"n1820939768":{"id":"n1820939768","loc":[-85.1327989,42.0704769]},"n1820939770":{"id":"n1820939770","loc":[-85.0588558,42.1047696]},"n1820939772":{"id":"n1820939772","loc":[-85.555798,41.9713017]},"n1820939773":{"id":"n1820939773","loc":[-85.0565853,42.1023589]},"n1820939774":{"id":"n1820939774","loc":[-85.2582941,41.9992765]},"n1820939775":{"id":"n1820939775","loc":[-85.3007264,41.9727642]},"n1820939776":{"id":"n1820939776","loc":[-85.2477045,42.0082652]},"n1820939777":{"id":"n1820939777","loc":[-85.2415247,42.0104973]},"n1821006698":{"id":"n1821006698","loc":[-85.6345227,41.9382009]},"n1821006700":{"id":"n1821006700","loc":[-85.6344894,41.938975]},"n1821006704":{"id":"n1821006704","loc":[-85.6351181,41.9370157]},"n1821006706":{"id":"n1821006706","loc":[-85.6357554,41.9361657]},"n1821006708":{"id":"n1821006708","loc":[-85.6351235,41.9368481]},"n1821006710":{"id":"n1821006710","loc":[-85.6352844,41.9364211]},"n1821006712":{"id":"n1821006712","loc":[-85.6351503,41.937307]},"n1821006716":{"id":"n1821006716","loc":[-85.6350366,41.9379774]},"n1821006725":{"id":"n1821006725","loc":[-85.6352147,41.9375903]},"n1821137607":{"id":"n1821137607","loc":[-85.5297057,41.9669915]},"n1821137608":{"id":"n1821137608","loc":[-85.5288598,41.9673094]},"n1821139530":{"id":"n1821139530","loc":[-85.4832228,41.9881686]},"n1821139531":{"id":"n1821139531","loc":[-85.4812101,41.9851258]},"n1821139532":{"id":"n1821139532","loc":[-85.4799127,41.9860244]},"n1821139533":{"id":"n1821139533","loc":[-85.4800313,41.9865555]},"n1841425201":{"id":"n1841425201","loc":[-85.4334577,42.0063713]},"n1841425222":{"id":"n1841425222","loc":[-85.4382449,42.0055785]},"n1914861007":{"id":"n1914861007","loc":[-85.394959,42.0057472]},"n1914861057":{"id":"n1914861057","loc":[-85.3967185,42.0049695]},"n1914861112":{"id":"n1914861112","loc":[-85.394179,42.0056906]},"n1914861306":{"id":"n1914861306","loc":[-85.3900226,42.0028488]},"n2114807565":{"id":"n2114807565","loc":[-85.6385979,41.9577824]},"n2114807568":{"id":"n2114807568","loc":[-85.6325097,41.9775713]},"n2114807572":{"id":"n2114807572","loc":[-85.6328996,41.9980965]},"n2114807578":{"id":"n2114807578","loc":[-85.6344818,41.9696956]},"n2114807583":{"id":"n2114807583","loc":[-85.6326289,41.9757853]},"n2114807593":{"id":"n2114807593","loc":[-85.6360828,41.9650674]},"n2130304159":{"id":"n2130304159","loc":[-85.6352537,41.9450015],"tags":{"railway":"level_crossing"}},"n2139795852":{"id":"n2139795852","loc":[-85.6374708,41.9311633]},"n2139858882":{"id":"n2139858882","loc":[-85.635178,41.9356158]},"n2139858883":{"id":"n2139858883","loc":[-85.63533,41.9355886]},"n2139858884":{"id":"n2139858884","loc":[-85.6353819,41.93556]},"n2139858885":{"id":"n2139858885","loc":[-85.6353665,41.9355157]},"n2139858886":{"id":"n2139858886","loc":[-85.6353165,41.9354971]},"n2139858887":{"id":"n2139858887","loc":[-85.6352454,41.9355328]},"n2139858888":{"id":"n2139858888","loc":[-85.6350184,41.9357846]},"n2139858889":{"id":"n2139858889","loc":[-85.634978,41.9359448]},"n2139858890":{"id":"n2139858890","loc":[-85.6347723,41.9361523]},"n2139858891":{"id":"n2139858891","loc":[-85.6347165,41.9362667]},"n2139858892":{"id":"n2139858892","loc":[-85.6346992,41.9364312]},"n2139858893":{"id":"n2139858893","loc":[-85.634603,41.9366329]},"n2139858894":{"id":"n2139858894","loc":[-85.6345973,41.9367488]},"n2139858895":{"id":"n2139858895","loc":[-85.6345127,41.9369734]},"n2139858896":{"id":"n2139858896","loc":[-85.634478,41.9371923]},"n2139858897":{"id":"n2139858897","loc":[-85.6344838,41.9373768]},"n2139858898":{"id":"n2139858898","loc":[-85.6346242,41.9375299]},"n2139858899":{"id":"n2139858899","loc":[-85.6347723,41.9376357]},"n2139858900":{"id":"n2139858900","loc":[-85.6347607,41.9377788]},"n2139858901":{"id":"n2139858901","loc":[-85.6346204,41.9379533]},"n2139858902":{"id":"n2139858902","loc":[-85.6344184,41.9380105]},"n2139858903":{"id":"n2139858903","loc":[-85.6341627,41.9380406]},"n2139858904":{"id":"n2139858904","loc":[-85.634005,41.9381679]},"n2139858905":{"id":"n2139858905","loc":[-85.63393,41.9383353]},"n2139858906":{"id":"n2139858906","loc":[-85.6338588,41.9384597]},"n2139858907":{"id":"n2139858907","loc":[-85.6336627,41.9387759]},"n2139858908":{"id":"n2139858908","loc":[-85.6335127,41.9389361]},"n2139858933":{"id":"n2139858933","loc":[-85.6353118,41.9432646]},"n2139858934":{"id":"n2139858934","loc":[-85.6353952,41.9433002]},"n2139858935":{"id":"n2139858935","loc":[-85.6356496,41.9433255]},"n2139858936":{"id":"n2139858936","loc":[-85.6363128,41.9433373]},"n2139858937":{"id":"n2139858937","loc":[-85.6365467,41.9433779]},"n2139858938":{"id":"n2139858938","loc":[-85.6368692,41.9435265]},"n2139858939":{"id":"n2139858939","loc":[-85.6370986,41.9437039]},"n2139858940":{"id":"n2139858940","loc":[-85.6372371,41.9437732]},"n2139858941":{"id":"n2139858941","loc":[-85.6374756,41.9438171]},"n2139858942":{"id":"n2139858942","loc":[-85.6376164,41.9439286]},"n2139858943":{"id":"n2139858943","loc":[-85.6377504,41.944138]},"n2139858944":{"id":"n2139858944","loc":[-85.6384204,41.9443137]},"n2139858945":{"id":"n2139858945","loc":[-85.6385726,41.9444506]},"n2139858946":{"id":"n2139858946","loc":[-85.638702,41.9445739]},"n2139858947":{"id":"n2139858947","loc":[-85.6387179,41.9446516]},"n2139858948":{"id":"n2139858948","loc":[-85.6387088,41.9447985]},"n2139858949":{"id":"n2139858949","loc":[-85.6387656,41.9449877]},"n2139858950":{"id":"n2139858950","loc":[-85.638777,41.9451448]},"n2139858951":{"id":"n2139858951","loc":[-85.6387088,41.9452631]},"n2139858964":{"id":"n2139858964","loc":[-85.6383346,41.9442912]},"n2139858966":{"id":"n2139858966","loc":[-85.6384724,41.9443605]},"n2139858967":{"id":"n2139858967","loc":[-85.6354078,41.9434285]},"n2139858968":{"id":"n2139858968","loc":[-85.635271,41.943654]},"n2139858969":{"id":"n2139858969","loc":[-85.6352657,41.9437437]},"n2139858970":{"id":"n2139858970","loc":[-85.635271,41.9438195]},"n2139858971":{"id":"n2139858971","loc":[-85.6351563,41.9438906]},"n2139858972":{"id":"n2139858972","loc":[-85.6351384,41.9438882]},"n2139858973":{"id":"n2139858973","loc":[-85.6351514,41.9438034]},"n2139858974":{"id":"n2139858974","loc":[-85.6351237,41.9436641]},"n2139858975":{"id":"n2139858975","loc":[-85.6351498,41.9436108]},"n2139858976":{"id":"n2139858976","loc":[-85.6351058,41.9435345]},"n2139858977":{"id":"n2139858977","loc":[-85.6349641,41.9432051]},"n2139858986":{"id":"n2139858986","loc":[-85.6341205,41.9380746]},"n2139858990":{"id":"n2139858990","loc":[-85.6345671,41.9381816]},"n2139858995":{"id":"n2139858995","loc":[-85.6339783,41.9382273]},"n2139859003":{"id":"n2139859003","loc":[-85.6340477,41.9373489]},"n2139859004":{"id":"n2139859004","loc":[-85.6339784,41.9374752]},"n2139870406":{"id":"n2139870406","loc":[-85.6342265,41.9432605]},"n2139877106":{"id":"n2139877106","loc":[-85.6346323,41.9438746]},"n2139982399":{"id":"n2139982399","loc":[-85.6324055,41.9408537]},"n2139982400":{"id":"n2139982400","loc":[-85.632488,41.941063],"tags":{"leisure":"slipway"}},"n2139982401":{"id":"n2139982401","loc":[-85.6327261,41.9415366]},"n2139982402":{"id":"n2139982402","loc":[-85.6326391,41.9413598]},"n2139982403":{"id":"n2139982403","loc":[-85.6327041,41.9414391]},"n2139982405":{"id":"n2139982405","loc":[-85.6322891,41.9406009]},"n2139982406":{"id":"n2139982406","loc":[-85.6325412,41.9425257]},"n2139989333":{"id":"n2139989333","loc":[-85.6340584,41.9431731]},"n2140006331":{"id":"n2140006331","loc":[-85.6361751,41.9459744]},"n2140006334":{"id":"n2140006334","loc":[-85.636528,41.9459751]},"n2140006336":{"id":"n2140006336","loc":[-85.6370918,41.9458926]},"n2140006338":{"id":"n2140006338","loc":[-85.6378806,41.9456474]},"n2140006340":{"id":"n2140006340","loc":[-85.6385831,41.9454343]},"n2140006342":{"id":"n2140006342","loc":[-85.639341,41.945157]},"n2140006344":{"id":"n2140006344","loc":[-85.6393497,41.9450232]},"n2140006346":{"id":"n2140006346","loc":[-85.6388245,41.9450145]},"n2140006348":{"id":"n2140006348","loc":[-85.6388167,41.9441739]},"n2140006351":{"id":"n2140006351","loc":[-85.6382915,41.9441797]},"n2140006353":{"id":"n2140006353","loc":[-85.63828,41.9438109]},"n2140006355":{"id":"n2140006355","loc":[-85.6381949,41.9436009]},"n2140006357":{"id":"n2140006357","loc":[-85.6371904,41.9435918]},"n2140006359":{"id":"n2140006359","loc":[-85.6366966,41.9432727]},"n2140006361":{"id":"n2140006361","loc":[-85.6353755,41.9432744]},"n2140006365":{"id":"n2140006365","loc":[-85.6350906,41.9435472]},"n2140006366":{"id":"n2140006366","loc":[-85.6343461,41.9441573]},"n2140006395":{"id":"n2140006395","loc":[-85.6351171,41.9437175]},"n2140006397":{"id":"n2140006397","loc":[-85.635352,41.9450206]},"n2140006399":{"id":"n2140006399","loc":[-85.6358194,41.9454937]},"n2140006401":{"id":"n2140006401","loc":[-85.6348693,41.9445739]},"n2140006431":{"id":"n2140006431","loc":[-85.6376737,41.9438023]},"n2140006437":{"id":"n2140006437","loc":[-85.6382631,41.9442724]},"n2189123379":{"id":"n2189123379","loc":[-85.6342671,41.9352665]},"w203974076":{"id":"w203974076","tags":{"highway":"footway"},"nodes":["n2139870442","n2139870457","n2139870458","n2139870459","n2139870460","n2139870452"]},"w170989131":{"id":"w170989131","tags":{"name":"St Joseph River","waterway":"river"},"nodes":["n1820938225","n1820938712","n1820937596","n1820937574","n1820938515","n1820938330","n1820938678","n1820938240","n1820938950","n1820939226","n1820939575","n1820937913","n1820938223","n1820937668","n1820938545","n1820937584","n1820939742","n1820939727","n1820937578","n1820938149","n1820938124","n1820938888","n1820938898","n1820937922","n1820939543","n1820939370","n1820939401","n1820939647","n1820938345","n1820939644","n1820938333","n1820938370","n1820938624","n1820938493","n1820939559","n1820939763","n1820939237","n1820939416","n1820937810","n1820938317","n1820938324","n1820937558","n1820939556","n1820938298","n1820939348","n1820939125","n1820939081","n1820938859","n1820939126","n1820938881","n1820939439","n1820939324","n1820939128","n1820938101","n1820937706","n1820938382","n1820938776","n1820937815","n1820939177","n1820939688","n1820938952","n1820938216","n1820938387","n1820939333","n1820938243","n1820938248","n1820937666","n1820939051","n1820938332","n1820939438","n1820939407","n1820939361","n1820937517","n1820938770","n1820939591","n1820937857","n1820938491","n1820937993","n1820938125","n1820938166","n1820937746","n1820939028","n1820937638","n1820938676","n1820938843","n1820938844","n1820937978","n1820938730","n1820939544","n1820938304","n1820939123","n1820939494","n1820939450","n1820939555","n1820938133","n1820938129","n1820938871","n1820939408","n1820938669","n1820938260","n1820939740","n1820937625","n1820938631","n1820939651","n1820939613","n1820937850","n1820938325","n1820937736","n1820938804","n1820938837","n1820938014","n1820938991","n1820938722","n1820938935","n1820937870","n1820938432","n1820937986","n1820938756","n1820938966","n1820939159","n1820937744","n1820938334","n1820937645","n1820939394","n1820937656","n1820938392","n1820939703","n1820938385","n1820938947","n1820938854","n1820938428","n1820938488","n1820938269","n1820938668","n1820938268","n1820938707","n1820937732","n1820939144","n1820938481","n1820938771","n1820938686","n1820938948","n1820937997","n1820937769","n1820939003","n1820938083","n1820939011","n1820938803","n1820938700","n1820939723","n1820938808","n1820938262","n1820938081","n1820938926","n1820938326","n1820938102","n1820938508","n1820939590","n1820939199","n1820938084","n1820938870","n1820938895","n1820937611","n1820938918","n1820938514","n1820939610","n1820938910","n1820937523","n1820938127","n1820939108","n1820937981","n1820938938","n1820938715","n1820939016","n1820938237","n1820939623","n1820939602","n1820937734","n1820938977","n1820939633","n1820939156","n1820939406","n1820938279","n1820938301","n1820937678","n1820937671","n1820939163","n1820938356","n1820939372","n1820937568","n1820937626","n1820939710","n1820939004","n1820938253","n1820938571","n1820937513","n1820939412","n1820939701","n1820939509","n1820938839","n1820939731","n1820937798","n1820939676","n1820939724","n1820939243","n1820939704","n1820937814","n1820937599","n1820938199","n1820938995","n1820938445","n1820938069","n1820938470","n1820939074","n1820938193","n1820938740","n1820938047","n1820939507","n1820939441","n1820939160","n1820937849","n1820937840","n1820938052","n1820938988","n1820938796","n1820937724","n1820937620","n1820939304","n1820938343","n1820939649","n1820938875","n1820939686","n1820938476","n1820937801","n1820937737","n1820938264","n1820939609","n1820939496","n1820939593","n1820939566","n1820939661","n1820937782","n1820938912","n1820939173","n1820937733","n1820938953","n1820939603","n1820937607","n1820938468","n1820939601","n1820939694","n1820939133","n1820938897","n1820938893","n1820937831","n1820937730","n1820938820","n1820938046","n1820938426","n1820938347","n1820937582","n1820938954","n1820938033","n1820938104","n1820938680","n1820939563","n1820939404","n1820939714","n1820939000","n1820937992","n1820938168","n1820939510","n1820939500","n1820937509","n1820938865","n1820939773","n1820938138","n1820938905","n1820937623","n1820939418","n1820937946","n1820939577","n1820937615","n1820939687","n1820939119","n1820937988","n1820938337","n1820937750","n1820938703","n1820938339","n1820939044","n1820939770","n1820938913","n1820937672","n1820939722","n1820937768","n1820939597","n1820939612","n1820937699","n1820937682","n1820937669","n1820937657","n1820939363","n1820937800","n1820938265","n1820937760","n1820938207","n1820938115","n1820939130","n1820939716","n1820938338","n1820938239","n1820939040","n1820938064","n1820938855","n1820939015","n1820938258","n1820939042","n1820939043","n1820938443","n1820939725","n1820937675","n1820938568","n1820938280","n1820937705","n1820938775","n1820938636","n1820938626","n1820937859","n1820938096","n1820937852","n1820939039","n1820938247","n1820938585","n1820937707","n1820938117","n1820938909","n1820939115","n1820939335","n1820938805","n1820937935","n1820937876","n1820938699","n1820937869","n1820938603","n1820938100","n1820938500","n1820938283","n1820938275","n1820938923","n1820938365","n1820938349","n1820937804","n1820937903","n1820937608","n1820938688","n1820939671","n1820938092","n1820937820","n1820938753","n1820938922","n1820937990","n1820939682","n1820939738","n1820939600","n1820938167","n1820937726","n1820939702","n1820938209","n1820939456","n1820937837","n1820938222","n1820938902","n1820939162","n1820938965","n1820938461","n1820937681","n1820937514","n1820937764","n1820939719","n1820939697","n1820938899","n1820939093","n1820938702","n1820939595","n1820938749","n1820938348","n1820937606","n1820938675","n1820938830","n1820938737","n1820938758","n1820938716","n1820939107","n1820937863","n1820939033","n1820938163","n1820937867","n1820938819","n1820938034","n1820938252","n1820937563","n1820937868","n1820939032","n1820938632","n1820937982","n1820937943","n1820939568","n1820939541","n1820938215","n1820939097","n1820938812","n1820937518","n1820937952","n1820938711","n1820938736","n1820939066","n1820937591","n1820938082","n1820938108","n1820938496","n1820939410","n1820938949","n1820938327","n1820937708","n1820939023","n1820937772","n1820938256","n1820939083","n1820938378","n1820938961","n1820937610","n1820939717","n1820938695","n1820938590","n1820939655","n1820938341","n1820939054","n1820939157","n1820939674","n1820939684","n1820939511","n1820937631","n1820939458","n1820937830","n1820937709","n1820937779","n1820939749","n1820938880","n1820938856","n1820938557","n1820939557","n1820938249","n1820938818","n1820937594","n1820939114","n1820938416","n1820937508","n1820938990","n1820938201","n1820937759","n1820937987","n1820939164","n1820939753","n1820938187","n1820939067","n1820937586","n1820937941","n1820938121","n1820937807","n1820938521","n1820939726","n1820938244","n1820939014","n1820938741","n1820937629","n1820938664","n1820938747","n1820939082","n1820938709","n1820938320","n1820938270","n1820937619","n1820937777","n1820937718","n1820939138","n1820938056","n1820938155","n1820938596","n1820937775","n1820938437","n1820938128","n1820939581","n1820939145","n1820938546","n1820938184","n1820937601","n1820937794","n1820938539","n1820939645","n1820938438","n1820938436","n1820939025","n1820938915","n1820938534","n1820937605","n1820939607","n1820939101","n1820939580","n1820939268","n1820939134","n1820938849","n1820938754","n1820938079","n1820937842","n1820938781","n1820938873","n1820938495","n1820938381","n1820938503","n1820939436","n1820938502","n1820939087","n1820938996","n1820938449","n1820938907","n1820937979","n1820937780","n1820937546","n1820939699","n1820937677","n1820938957","n1820938946","n1820937776","n1820937717","n1820938718","n1820937637","n1820938510","n1820937663","n1820938941","n1820939151","n1820937603","n1820938250","n1820937951","n1820938630","n1820938821","n1820938779","n1820938497","n1820938159","n1820939536","n1820938409","n1820938386","n1820939116","n1820938340","n1820939117","n1820938291","n1820938435","n1820937819","n1820938242","n1820939078","n1820938877","n1820939104","n1820939445","n1820938367","n1820938903","n1820939420","n1820938517","n1820939508","n1820939542","n1820939326","n1820938210","n1820939020","n1820938815","n1820937832","n1820939513","n1820937818","n1820939005","n1820938717","n1820939135","n1820938384","n1820937587","n1820939024","n1820939504","n1820939120","n1820939026","n1820938015","n1820938998","n1820937648","n1820939137","n1820937761","n1820938195","n1820938535","n1820939550","n1820938725","n1820938282","n1820937781","n1820937792","n1820939705","n1820937788","n1820939707","n1820937882","n1820939632","n1820938427","n1820938276","n1820939617","n1820939013","n1820939035","n1820937543","n1820939365","n1820937752","n1820937802","n1820939183","n1820939670","n1820938450","n1820939375","n1820937813","n1820937673","n1820937783","n1820939029","n1820939768","n1820939377","n1820937974","n1820939244","n1820939642","n1820937864","n1820938255","n1820938528","n1820939666","n1820938120","n1820937812","n1820938928","n1820939750","n1820939099","n1820938073","n1820938714","n1820939140","n1820938192","n1820937844","n1820938635","n1820938742","n1820939583","n1820937887","n1820938318","n1820938816","n1820939698","n1820938273","n1820939181","n1820937652","n1820938748","n1820937651","n1820938519","n1820938019","n1820938752","n1820938235","n1820939118","n1820938562","n1820939314","n1820939570","n1820938190","n1820938342","n1820938533","n1820937977","n1820939089","n1820939146","n1820938622","n1820938297","n1820938524","n1820939283","n1820938874","n1820938832","n1820937550","n1820937843","n1820938638","n1820938116","n1820938206","n1820938319","n1820939053","n1820937845","n1820938093","n1820939217","n1820938997","n1820939355","n1820938861","n1820938726","n1820938057","n1820939373","n1820937862","n1820938518","n1820939072","n1820939680","n1820938444","n1820938217","n1820938506","n1820938393","n1820938492","n1820938852","n1820938221","n1820938773","n1820937684","n1820939060","n1820938224","n1820938203","n1820938840","n1820937525","n1820938147","n1820938433","n1820938188","n1820939359","n1820938750","n1820938016","n1820938768","n1820937621","n1820937799","n1820938951","n1820938721","n1820939037","n1820937866","n1820939715","n1820938063","n1820938446","n1820937627","n1820939624","n1820938431","n1820939721","n1820939622","n1820939239","n1820939263","n1820939648","n1820939640","n1820938867","n1820938757","n1820938439","n1820939352","n1820937740","n1820939329","n1820938229","n1820937583","n1820938180","n1820938366","n1820937767","n1820937758","n1820939374","n1820938869","n1820938292","n1820938400","n1820938399","n1820939734","n1820939289","n1820938944","n1820937755","n1820938759","n1820938434","n1820937600","n1820937825","n1820937670","n1820937793","n1820938011","n1820938246","n1820938956","n1820937770","n1820937757","n1820938059","n1820937860","n1820937569","n1820939266","n1820939685","n1820939672","n1820938606","n1820938772","n1820939038","n1820938211","n1820938359","n1820939619","n1820938708","n1820939512","n1820938065","n1820939233","n1820939739","n1820938786","n1820938879","n1820939147","n1820938563","n1820939148","n1820937839","n1820937659","n1820937786","n1820938419","n1820939565","n1820939402","n1820937710","n1820938254","n1820938271","n1820938390","n1820937680","n1820938140","n1820937817","n1820938218","n1820937985","n1820939235","n1820938441","n1820938401","n1820938719","n1820937795","n1820938971","n1820938460","n1820939759","n1820937972","n1820937841","n1820938462","n1820939320","n1820938978","n1820938360","n1820939713","n1820937676","n1820939712","n1820937939","n1820938080","n1820937754","n1820937753","n1820938530","n1820937886","n1820939689","n1820939124","n1820938697","n1820938789","n1820939105","n1820938860","n1820938853","n1820939400","n1820937561","n1820938404","n1820938774","n1820939316","n1820937696","n1820938782","n1820938975","n1820937564","n1820939730","n1820938257","n1820937853","n1820938487","n1820938848","n1820938906","n1820939230","n1820938424","n1820938051","n1820937771","n1820939587","n1820939149","n1820938792","n1820939041","n1820938934","n1820939777","n1820937515","n1820939058","n1820938312","n1820939264","n1820939631","n1820939109","n1820939403","n1820939664","n1820938724","n1820938929","n1820939399","n1820939776","n1820939369","n1820939185","n1820937701","n1820938126","n1820938336","n1820938219","n1820939080","n1820938642","n1820938043","n1820937725","n1820938548","n1820938552","n1820938035","n1820938684","n1820937778","n1820938764","n1820939021","n1820939346","n1820937712","n1820939761","n1820938397","n1820937747","n1820938566","n1820939161","n1820939090","n1820939752","n1820939271","n1820938878","n1820938110","n1820938346","n1820938499","n1820938151","n1820939538","n1820938281","n1820939153","n1820938551","n1820939285","n1820938197","n1820938408","n1820938482","n1820939036","n1820939579","n1820938489","n1820938483","n1820938189","n1820938123","n1820938087","n1820937741","n1820938485","n1820937590","n1820938972","n1820937773","n1820937520","n1820938872","n1820938131","n1820938452","n1820938328","n1820939620","n1820937641","n1820938353","n1820939693","n1820938705","n1820937640","n1820939189","n1820938144","n1820939774","n1820938694","n1820938238","n1820939397","n1820937917","n1820938454","n1820938567","n1820938979","n1820938060","n1820938204","n1820937828","n1820939232","n1820938806","n1820938857","n1820938078","n1820938105","n1820939228","n1820938604","n1820937763","n1820937854","n1820938289","n1820939736","n1820937937","n1820937714","n1820938278","n1820938058","n1820938706","n1820938989","n1820938313","n1820938520","n1820938288","n1820937689","n1820939537","n1820939531","n1820939019","n1820937527","n1820938455","n1820938814","n1820938045","n1820939627","n1820938213","n1820938161","n1820938331","n1820938024","n1820938220","n1820938062","n1820938178","n1820937796","n1820937644","n1820938490","n1820937589","n1820937879","n1820939614","n1820938882","n1820938039","n1820938538","n1820937667","n1820937719","n1820938561","n1820939658","n1820938783","n1820938601","n1820938198","n1820938388","n1820938969","n1820937687","n1820939086","n1820939665","n1820939187","n1820938498","n1820938261","n1820937983","n1820938068","n1820938136","n1820939061","n1820938137","n1820938186","n1820939071","n1820937592","n1820939669","n1820937553","n1820939357","n1820938727","n1820939371","n1820939112","n1820939079","n1820938743","n1820938467","n1820938834","n1820938022","n1820938537","n1820938122","n1820938516","n1820937614","n1820937612","n1820939469","n1820939636","n1820939050","n1820939552","n1820938157","n1820938663","n1820938955","n1820939091","n1820938430","n1820938471","n1820937809","n1820938074","n1820938208","n1820938914","n1820938858","n1820938417","n1820937531","n1820938107","n1820939100","n1820938751","n1820937711","n1820938824","n1820939745","n1820937572","n1820938602","n1820938212","n1820938097","n1820937921","n1820938090","n1820938511","n1820938876","n1820939762","n1820938234","n1820938048","n1820937774","n1820937856","n1820937749","n1820937765","n1820938286","n1820939095","n1820938480","n1820939229","n1820938277","n1820937617","n1820938311","n1820937622","n1820939196","n1820937690","n1820939006","n1820939287","n1820939131","n1820938106","n1820938784","n1820938335","n1820938095","n1820938182","n1820937715","n1820937683","n1820938070","n1820939605","n1820938527","n1820938763","n1820938398","n1820937686","n1820939621","n1820937664","n1820939277","n1820938565","n1820939539","n1820938099","n1820939646","n1820938556","n1820937548","n1820938729","n1820939336","n1820938259","n1820938728","n1820938361","n1820937643","n1820938644","n1820939007","n1820939690","n1820939227","n1820937635","n1820937950","n1820938682","n1820939150","n1820939012","n1820939261","n1820939111","n1820937805","n1820939691","n1820939677","n1820937628","n1820937811","n1820938790","n1820938251","n1820938226","n1820938942","n1820937633","n1820937984","n1820937751","n1820939673","n1820938970","n1820938415","n1820938597","n1820938309","n1820938111","n1820938472","n1820938894","n1820938402","n1820937593","n1820938570","n1820939102","n1820939775","n1820937948","n1820939121","n1820937511","n1820938787","n1820939720","n1820939075","n1820937880","n1820937742","n1820937721","n1820939535","n1820938486","n1820938354","n1820937632","n1820939010","n1820938885","n1820938089","n1820937613","n1820938442","n1820938245","n1820938272","n1820937566","n1820938295","n1820938532","n1820938883","n1820937713","n1820937674","n1820939635","n1820938448","n1820938355","n1820938587","n1820938559","n1820937787","n1820939301","n1820937723","n1820939056","n1820937560","n1820938323","n1820938230","n1820938453","n1820938377","n1820938357","n1820939637","n1820938017","n1820939540","n1820939376","n1820937639","n1820937642","n1820938075","n1820938351","n1820938766","n1820937897","n1820938973","n1820938066","n1820939547","n1820939652","n1820937944","n1820937748","n1820939234","n1820939193","n1820937891","n1820938785","n1820939132","n1820938523","n1820938884","n1820938411","n1820939554","n1820938791","n1820937655","n1820938368","n1820939152","n1820938030","n1820938447","n1820937580","n1820939628","n1820937588","n1820937894","n1820939201","n1820938086","n1820937650","n1820938379","n1820939008","n1820938999","n1820937524","n1820937872","n1820938389","n1820939197","n1820938422","n1820938936","n1820939262","n1820937634","n1820938583","n1820939589","n1820937901","n1820939034","n1820939065","n1820938290","n1820939195","n1820938228","n1820937884","n1820938797","n1820938191","n1820939191","n1820939198","n1820937892","n1820939679","n1820938507","n1820937647","n1820937909","n1820938542","n1820939598","n1820937851","n1820939084","n1820939728","n1820937688","n1820938263","n1820938670","n1820937762","n1820939310","n1820938925","n1820938862","n1820938822","n1820938547","n1820937731","n1820938594","n1820938592","n1820938214","n1820938284","n1820937835","n1820938599","n1820939437","n1820937834","n1820937576","n1820937692","n1820939586","n1820939546","n1820938403","n1820937970","n1820939561","n1820938098","n1820938851","n1820938477","n1820938892","n1820939045","n1820939758","n1820939350","n1820938321","n1820938440","n1820938595","n1820938364","n1820938962","n1820938118","n1820939678","n1820938406","n1820938549","n1820937555","n1820938823","n1820937521","n1820939471","n1820939487","n1820938799","n1820938605","n1820937928","n1820938373","n1820939747","n1820939629","n1820937557","n1820937526","n1820938958","n1820938833","n1820937636","n1820938967","n1820938760","n1820938842","n1820938067","n1820939077","n1820939224","n1820938185","n1820939110","n1820938372","n1820939757","n1820939063","n1820939660","n1820938813","n1820937528","n1820938369","n1820938896","n1820939551","n1820939683","n1820937660","n1820937873","n1820938810","n1820938478","n1820939662","n1820937595","n1820939052","n1820938113","n1820939070","n1820938733","n1820937878","n1820938300","n1820939760","n1820939718","n1820937646","n1820939057","n1820939443","n1914861306","n1820938013","n1820937529","n1820939764","n1820938826","n1820937885","n1820939588","n1820937865","n1820937833","n1914861112","n1820938761","n1914861007","n1820937905","n1820938541","n1820939092","n1914861057","n1820938153","n1820938267","n1820939265","n1820938085","n1820939018","n1820939755","n1820938474","n1820939027","n1820938593","n1820938202","n1820939599","n1820939695","n1820938077","n1820938012","n1820939545","n1820939596","n1820939337","n1820938227","n1820937698","n1820938475","n1820939465","n1820938165","n1820938698","n1820938525","n1820938529","n1820938553","n1820938940","n1820939498","n1820938501","n1820939533","n1820938924","n1820939634","n1820939220","n1820939657","n1820938887","n1820938838","n1820938114","n1820937823","n1820938778","n1820938801","n1820939096","n1820938981","n1820937953","n1820938732","n1820938980","n1820938960","n1820937949","n1820938026","n1820939273","n1841425201","n1820938629","n1820938864","n1820938554","n1820938088","n1820937685","n1841425222","n1820939729","n1820937665","n1820937838","n1820937739","n1820938780","n1820937821","n1820938825","n1820939055","n1820939485","n1820938041","n1820938746","n1820939562","n1820938459","n1820939489","n1820938050","n1820937980","n1820937695","n1820938413","n1820938555","n1820937703","n1820938536","n1820938196","n1820938287","n1820938169","n1820939279","n1820938531","n1820938959","n1820939741","n1820938665","n1820938963","n1820939611","n1820937653","n1820939618","n1820939492","n1820938600","n1820938628","n1820939312","n1820939616","n1820937738","n1820939001","n1820939062","n1820938794","n1820938558","n1820937822","n1820937532","n1820939073","n1820938200","n1820938241","n1820938968","n1820938927","n1820938306","n1820937630","n1820938456","n1820937694","n1820938908","n1820939076","n1820937522","n1820939659","n1820938522","n1820939318","n1820938932","n1820938841","n1820937579","n1820937540","n1820938560","n1821139530","n1820938964","n1820937662","n1820939281","n1821139533","n1820937797","n1821139532","n1820939751","n1821139531","n1820939291","n1820938420","n1820939696","n1820938904","n1820938484","n1820939448","n1820939009","n1820938735","n1820938986","n1820938937","n1820939030","n1820938734","n1820938745","n1820939106","n1820938987","n1820937858","n1820938673","n1820938620","n1820937808","n1820937700","n1820939573","n1820938540","n1820937661","n1820937570","n1820938396","n1820937875","n1820939048","n1820938233","n1820938793","n1820939584","n1820938412","n1820938394","n1820937846","n1820938800","n1820938690","n1820939331","n1820939630","n1820938762","n1820938710","n1820939322","n1820938992","n1821137608","n1821137607","n1820937924","n1820939139","n1820939463","n1820939574","n1820938294","n1820938071","n1820938307","n1820938061","n1820939260","n1820937899","n1820938310","n1820938983","n1820937530","n1820938993","n1820938890","n1820937915","n1820938231","n1820938040","n1820938920","n1820939585","n1820938135","n1820939700","n1820937824","n1820939667","n1820937930","n1820938134","n1820937551","n1820939405","n1820938232","n1820937716","n1820937848","n1820939765","n1820939068","n1820939766","n1820937933","n1820937720","n1820939222","n1820939772","n1820939022","n1820939732","n1820937702","n1820937691","n1820938945","n1820937756","n1820938451","n1820938410","n1820938798","n1820937945","n1820937654","n1820938598","n1820938836","n1820937571","n1820937556","n1820938994","n1820938919","n1820938863","n1820939064","n1820938018","n1820937658","n1820937537","n1820938142","n1820938666","n1820937535","n1820939571","n1820938465","n1820939638","n1820937533","n1820939656","n1820939422","n1820938109","n1820938405","n1820938028","n1820937649","n1820938829","n1820939031","n1820939155","n1820938350","n1820938463","n1820938425","n1820939047","n1820938831","n1820938494","n1820937697","n1820938504","n1820938900","n1820937784","n1820938414","n1820938076","n1820938723","n1820937722","n1820938739","n1820937791","n1820938985","n1820938352","n1820938293","n1820938274","n1820939692","n1820937871","n1820939059","n1820938868","n1820937877","n1820937743","n1820938429","n1820937545","n1820937575","n1820938302","n1820938505","n1820938916","n1820938374","n1820938329","n1820937790","n1820939735","n1820938930","n1820937995","n1820938512","n1820938130","n1820938194","n1820938671","n1820938802","n1820937542","n1820937602","n1820939069","n1820938901","n1820939654","n1820937727","n1820939569","n1820938375","n1820939306","n1820938479","n1820938376","n1820938667","n1820937766","n1820939467","n1820939567","n1820937806","n1820938943","n1820938931","n1820937745","n1820939452","n1820938738","n1820938053","n1820939653","n1820938640","n1820937604","n1820937536","n1820938701","n1820939625","n1820939744","n1820939572","n1820937577","n1820937541","n1820938891","n1820937597","n1820938469","n1820939194","n1820937539","n1820938911","n1820939017","n1820939650","n1820939103","n1820939578","n1820938132","n1820937549","n1820938634","n1820939743","n1820937544","n1820937826","n1820937598","n1820937547","n1820938032","n1820939142"]},"w17963021":{"id":"w17963021","tags":{"highway":"residential"},"nodes":["n185948706","n185948708","n185948710"]},"w203974069":{"id":"w203974069","tags":{"amenity":"shelter","area":"yes","building":"yes","shelter_type":"picnic_shelter"},"nodes":["n2139870431","n2139870432","n2139870433","n2139870434","n2139870431"]},"w209816575":{"id":"w209816575","tags":{"area":"yes","building":"yes"},"nodes":["n2199856288","n2199856289","n2199856290","n2199856291","n2199856292","n2199856293","n2199856294","n2199856295","n2199856296","n2199856297","n2199856298","n2199856299","n2199856300","n2199856301","n2199856302","n2199856303","n2199856288"]},"w203841838":{"id":"w203841838","tags":{"area":"yes","natural":"water"},"nodes":["n2138493826","n2138493827","n2138493828","n2138493829","n2138493830","n2138493831","n2138493833","n2138493832","n2138493826"]},"w203972937":{"id":"w203972937","tags":{"highway":"path","name":"Riverwalk Trail","surface":"asphalt","width":"3"},"nodes":["n2139858882","n2139858883","n2139858884","n2139858885","n2139858886","n2139858887","n2139858882","n2139858888","n2139858889","n2139858890","n2139858891","n2139858892","n2139858893","n2139858894","n2139858895","n2139858896","n2139858897","n2139858898","n2139858899","n2139858900","n2139858901","n2139858902","n2139858903","n2139858986","n2139858904","n2139858995","n2139858905","n2139858906","n2139858907","n2139858908","n2139858909","n2139858910","n2139858911","n2139858912","n2139858913","n2139858914","n2139858915","n2139858916","n2139858917","n2139858918","n2139858919","n2139858920","n2139858921","n2139858922","n2139858923","n2139858924","n2139858925","n2139858926","n2139858927","n2139858982","n2139858928","n2139858929","n2139858930","n2139858931","n2139858932","n2139858981","n2139858933","n2139858934","n2139858935","n2139858936","n2139858937","n2139858938","n2139858939","n2139858940","n2139858941","n2139858942","n2139858943","n2140006437","n2139858964","n2139858944","n2139858966","n2139858945","n2139858946","n2139858947","n2139858948","n2139858949","n2139858950","n2139858951"]},"w17964015":{"id":"w17964015","tags":{"highway":"residential"},"nodes":["n185954680","n185954683","n185954685","n185954687","n185954689","n185954690","n185954691","n2139870379","n2139870456","n185954692","n185954693","n185954695"]},"w17967315":{"id":"w17967315","tags":{"highway":"residential","name":"South Andrews Street"},"nodes":["n185981999","n185974477","n185964963"]},"w203974071":{"id":"w203974071","tags":{"highway":"footway"},"nodes":["n2139870439","n2139870440","n2139870441","n2139870442","n2139870443","n2139870444","n2139870445","n2139870446","n2139870447","n2139870448","n2139870449"]},"w170848824":{"id":"w170848824","tags":{"name":"Rocky River","waterway":"river"},"nodes":["n1819858503","n1819858531","n1819858526","n1819858518","n1819858505","n1819858508","n1819858512","n1819858514","n1819858528","n1819858509","n1819858511","n1819858507","n1819858521"]},"w203986458":{"id":"w203986458","tags":{"amenity":"shelter","area":"yes","shelter_type":"picnic_shelter"},"nodes":["n2139989357","n2139989359","n2139989360","n2139989362","n2139989357"]},"w170844917":{"id":"w170844917","tags":{"waterway":"riverbank"},"nodes":["n1819805911","n1819805690","n1819805812","n1819805766","n1819805802","n1819805885","n1819805626","n1819805842","n1819805715","n1819805694","n1819805618","n1819805629","n1819805731","n1819805636","n1819805878","n1819805718","n1819805798","n1819849057","n1819805666","n1819805852","n1819805805","n1819805789","n1819805868","n1819805680","n1819805918","n1819848888","n1819805762","n2139989328","n1819805907","n2139989330","n1819805915","n1819858521","n1819805854","n1819805876","n1819805864","n1819805922","n2139859004","n1819805702","n2139859003","n1819805614","n1819805792","n1819805786","n1819805777","n1819805645","n1819805838","n1819805889","n1819805795","n1819805707","n1819805774","n1819805808","n1819805810","n1819805724","n1819805676","n1819805728","n1819805783","n1819805687","n1819805727","n2189123379","n1819805632","n1819805641","n1819805760","n1819805887","n1819805861","n1819805722","n1819805880","n2139982405","n2139982399","n2139982400","n1819805770","n2139982402","n2139982403","n2139982401","n1819805780","n1819805834","n2139982406","n1819805698","n1819805647","n1819805870","n1819805683","n1819805622","n1819805639","n1819805858","n1819805643","n1819805673","n1819805925","n1819805849","n1819805711","n1819805846","n1819805669","n1819805883","n1819805814","n1819805873","n1819805911"]},"w17967326":{"id":"w17967326","tags":{"highway":"residential","name":"North Constantine Street"},"nodes":["n185985217","n185985219","n185985221","n185985222","n185985223","n185985225","n2140006431","n185985227","n185985229","n185985231","n185985233","n185985235","n185985238","n185985240","n2140018998","n185964965"]},"w134150789":{"id":"w134150789","tags":{"highway":"primary","name":"West Michigan Avenue","old_ref":"US 131","ref":"US 131 Business;M 60"},"nodes":["n185964971","n2139870406","n185964972"]},"w17966400":{"id":"w17966400","tags":{"highway":"tertiary","name":"South Constantine Street"},"nodes":["n185958672","n185964965"]},"w203974066":{"id":"w203974066","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2139870417","n2139870418","n2139870420","n2139870419"]},"w17965998":{"id":"w17965998","tags":{"name":"Conrail Railroad","railway":"rail"},"nodes":["n185972775","n185972777","n185972779","n185972781","n185972783","n185972785","n185972787","n185972788","n185972789","n185972790","n185972791","n185972793","n185972795","n185972797","n185972798","n185972800","n185972802","n185972805","n185972807","n185972809","n185972811","n185972813","n185972814","n185972815","n185972816","n185972817","n185972819","n185972821","n185972824","n185972826","n185972830","n185972832","n185972834","n185972835","n185972836","n185972839","n185990434","n2114807572","n2114807568","n185972845","n2114807583","n185972847","n185972849","n185972851","n2114807578","n1475293254","n2114807593","n1475293226","n185972862","n2114807565","n185951869","n1475293234","n1475293252","n185972868","n1475293264","n1475293222","n185972878","n1475293261","n185972882","n185972885","n1475293260","n1475293240","n185972891","n185972895","n185972897","n185972899","n2130304159","n1475284023","n185972903"]},"w134150795":{"id":"w134150795","tags":{"bridge":"yes","highway":"primary","name":"West Michigan Avenue","old_ref":"US 131","ref":"US 131 Business;M 60"},"nodes":["n185964970","n185964971"]},"w203974067":{"id":"w203974067","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2139870420","n2139870421"]},"w170995908":{"id":"w170995908","tags":{"highway":"residential","name":"Thomas Street"},"nodes":["n1821006702","n1821006700","n1821006698","n2139858990","n1821006716","n1821006725","n1821006712","n1821006704","n1821006708","n1821006710","n1821006706"]},"w17965834":{"id":"w17965834","tags":{"highway":"residential","name":"Spring Street"},"nodes":["n185971361","n185971364","n185971366","n185971368","n185954695","n185964968"]},"w203974070":{"id":"w203974070","tags":{"amenity":"shelter","area":"yes","building":"yes","shelter_type":"picnic_shelter"},"nodes":["n2139870435","n2139870436","n2139870437","n2139870438","n2139870435"]},"w203989879":{"id":"w203989879","tags":{"highway":"service"},"nodes":["n2140018998","n2140018999","n2140019000"]},"w203974062":{"id":"w203974062","tags":{"amenity":"parking","area":"yes"},"nodes":["n2139870387","n2139870388","n2139870389","n2139870390","n2139870391","n2139870392","n2139870397","n2139870393","n2139870396","n2139870395","n2139870394","n2139870387"]},"w203974061":{"id":"w203974061","tags":{"bridge":"yes","highway":"footway"},"nodes":["n2139870382","n2139870383"]},"w203049587":{"id":"w203049587","tags":{"area":"yes","name":"Scidmore Park Petting Zoo","tourism":"zoo","zoo":"petting_zoo"},"nodes":["n2130304133","n2130304136","n2130304138","n2130304140","n2130304142","n2130304144","n2130304146","n2130304147","n2130304148","n2130304149","n2130304150","n2130304151","n2130304133"]},"w203972941":{"id":"w203972941","tags":{"highway":"path"},"nodes":["n2139858982","n2139858983","n2139858984","n2139858985","n2139858927"]},"w203974065":{"id":"w203974065","tags":{"highway":"service"},"nodes":["n2139870406","n2139870407","n2139870408","n2139870417","n2139870409","n2139870410","n2139870411","n2139870412","n2139870426","n2139870413","n2139870414","n2139870415","n2139870419","n2139870416","n2139870421","n2139870408"]},"w203972940":{"id":"w203972940","tags":{"highway":"path","name":"Riverwalk Trail"},"nodes":["n2139858934","n2139858967","n2139858968","n2139858969","n2139858970","n2139858971","n2139858972","n2139858973","n2139858974","n2139858975","n2139858976","n2139858977","n2139858978","n2139858979","n2139858980","n2139858981"]},"w203974072":{"id":"w203974072","tags":{"highway":"footway"},"nodes":["n2139858925","n2139870450","n2139870453","n2139870451","n2139870452","n2139870441"]},"w203974074":{"id":"w203974074","tags":{"highway":"footway"},"nodes":["n2139870454","n2139870456","n2139870429"]},"w203974060":{"id":"w203974060","tags":{"highway":"footway"},"nodes":["n2139870383","n2139870384","n2139870422","n2139870385","n2139870386","n2139870388"]},"w203841837":{"id":"w203841837","tags":{"area":"yes","natural":"water"},"nodes":["n2138493807","n2138493808","n2138493809","n2138493810","n2138493811","n2138493812","n2138493813","n2138493814","n2138493815","n2138493816","n2138493825","n2138493817","n2138493824","n2138493818","n2138493819","n2138493820","n2138493821","n2138493822","n2138493823","n2138493807"]},"w134150845":{"id":"w134150845","tags":{"bridge":"yes","name":"Conrail Railroad","railway":"rail"},"nodes":["n185972903","n185972905"]},"w203974059":{"id":"w203974059","tags":{"highway":"footway"},"nodes":["n2139870430","n2139870439","n2139870429","n2139870428","n2139870379","n2139870455","n2139870380","n2139870381","n2139858925","n2139870382"]},"w203986457":{"id":"w203986457","tags":{"area":"yes","leisure":"park","name":"Scidmore Park"},"nodes":["n2139989333","n2139989335","n2139989337","n2139989339","n1819805762","n2139989328","n1819805907","n2139989330","n1819805915","n2139989341","n2139989344","n2139989346","n2139989348","n2139989350","n2139989351","n2139989353","n2139989355","n2139989333"]},"w170848331":{"id":"w170848331","tags":{"name":"Rocky River","waterway":"river"},"nodes":["n1819848937","n1819849104","n1819849076","n1819849183","n1819848928","n1819848972","n1819848948","n1819848971","n1819848859","n1819849008","n1819848889","n1819849026","n1819849094","n1819849083","n1819849079","n1819849187","n1819848992","n1819849060","n1819849056","n1819849071","n1819849067","n1819849048","n1819849036","n1819849150","n1819849075","n1819849051","n1819849062","n1819848926","n1819849035","n1819848987","n1819849012","n1819848933","n1819848996","n1819848990","n1819849005","n1819849021","n1819848892","n1819849092","n1819848863","n1819848922","n1819848858","n1819848855","n1819848974","n1819848953","n1819849019","n1819849049","n1819848979","n1819849140","n1819849193","n1819849147","n1819849151","n1819849163","n1819849023","n1819848878","n1819849004","n1819848857","n1819848879","n1819849041","n1819849165","n1819849107","n1819849156","n1819848934","n1819848914","n1819848955","n1819848931","n1819848927","n1819849084","n1819849169","n1819849045","n1819848945","n1819849095","n1819848924","n1819849171","n1819849141","n1819849046","n1819849197","n1819849011","n1819849108","n1819849158","n1819849160","n1819848870","n1819849006","n1819849157","n1819848993","n1819848970","n1819849202","n1819848903","n1819848975","n1819848849","n1819849025","n1819849105","n1819849033","n1819849176","n1819849099","n1819849086","n1819848960","n1819848961","n1819849001","n1819848980","n1819849038","n1819848854","n1819849127","n1819849170","n1819849139","n1819848873","n1819848929","n1819849201","n1819849121","n1819849031","n1819849131","n1819848875","n1819849080","n1819849066","n1819849081","n1819849096","n1819849172","n1819849114","n1819849182","n1819848905","n1819849054","n1819848920","n1819848851","n1819848968","n1819848917","n1819849111","n1819849119","n1819849074","n1819848893","n1819849129","n1819848850","n1819848956","n1819849154","n1819848877","n1819848986","n1819849191","n1819848952","n1819848954","n1819848942","n1819849028","n1819849195","n1819848938","n1819848962","n1819849070","n1819849034","n1819849052","n1819849059","n1819848916","n1819849162","n1819849167","n1819849093","n1819849030","n1819849002","n1819849161","n1819848886","n1819848958","n1819849064","n1819849112","n1819849148","n1819848856","n1819848976","n1819848977","n1819849144","n1819848918","n1819849200","n1819848919","n1819849042","n1819849166","n1819849186","n1819849152","n1819849058","n1819849185","n1819849199","n1819849053","n1819849194","n1819849068","n1819849146","n1819849174","n1819848967","n1819848932","n1819849155","n1819849198","n1819848964","n1819848894","n1819848969","n1819849184","n1819849055","n1819849179","n1819848865","n1819848860","n1819849082","n1819848966","n1819849040","n1819849069","n1819849078","n1819849077","n1819848904","n1819848959","n1819849133","n1819849089","n1819849000","n1819849124","n1819849032","n1819849097","n1819848939","n1819849072","n1819848915","n1819849196","n1819848946","n1819849047","n1819849029","n1819849164","n1819848994","n1819849022","n1819858513","n1819849126","n1819849063","n1819848941","n1819849085","n1819848871","n1819848943","n1819849192","n1819858501","n1819849159","n1819858523","n1819848901","n1819849189","n1819858503","n1819849065","n2139877106","n1819848909","n1819848930","n1819848888"]},"w17967397":{"id":"w17967397","tags":{"highway":"residential","name":"North Andrews Street"},"nodes":["n185964963","n185985217"]},"w17964497":{"id":"w17964497","tags":{"highway":"tertiary","name":"Constantine St"},"nodes":["n185958643","n185958645","n2139795852","n185958647","n185958649","n185958651","n185958653","n185958656","n185958658","n185958660","n185958662","n185958664","n185958666","n185958668","n185958670","n185948710","n185958672"]},"w203974068":{"id":"w203974068","tags":{"highway":"footway"},"nodes":["n2139870422","n2139870423","n2139870424","n2139870425","n2139870426","n2139870427"]},"w203974063":{"id":"w203974063","tags":{"amenity":"parking","area":"yes"},"nodes":["n2139870398","n2139870399","n2139870400","n2139870401","n2139870398"]},"w203986459":{"id":"w203986459","tags":{"amenity":"shelter","area":"yes","shelter_type":"picnic_shelter"},"nodes":["n2139989364","n2139989366","n2139989368","n2139989370","n2139989364"]},"w203988286":{"id":"w203988286","tags":{"area":"yes","leisure":"park","name":"Memory Isle Park"},"nodes":["n2140006331","n2140006334","n2140006336","n2140006338","n2140006340","n2140006342","n2140006344","n2140006346","n2140006348","n2140006351","n2140006353","n2140006355","n2140006357","n2140006359","n2140006361","n2140006363","n2140006364","n2140006365","n2140006395","n2140006366","n2140006401","n2140006397","n2140006399","n2140006331"]},"w203974073":{"id":"w203974073","tags":{"highway":"footway"},"nodes":["n2139870453","n2139870454","n2139870455"]},"w203974064":{"id":"w203974064","tags":{"amenity":"parking","area":"yes"},"nodes":["n2139870402","n2139870403","n2139870404","n2139870405","n2139870402"]},"n185966959":{"id":"n185966959","loc":[-85.642185,41.946411]},"n1475283980":{"id":"n1475283980","loc":[-85.6398249,41.9451425]},"n1475284013":{"id":"n1475284013","loc":[-85.6396448,41.9451666]},"n1475284042":{"id":"n1475284042","loc":[-85.6386382,41.9454789]},"n185975925":{"id":"n185975925","loc":[-85.6393332,41.9452388]},"n185975919":{"id":"n185975919","loc":[-85.6391279,41.9453044]},"n185975917":{"id":"n185975917","loc":[-85.6389034,41.9453872]},"n2140006369":{"id":"n2140006369","loc":[-85.6386163,41.9451631]},"n2140006370":{"id":"n2140006370","loc":[-85.6385144,41.9449357]},"n2140006417":{"id":"n2140006417","loc":[-85.6385785,41.9450299]},"n2140006419":{"id":"n2140006419","loc":[-85.6385781,41.9452152]},"n2189123361":{"id":"n2189123361","loc":[-85.6404948,41.947015]},"n2189123363":{"id":"n2189123363","loc":[-85.6395765,41.946495]},"n2189123365":{"id":"n2189123365","loc":[-85.6389347,41.9460875]},"n185966962":{"id":"n185966962","loc":[-85.644417,41.946364]},"n185975911":{"id":"n185975911","loc":[-85.637532,41.9458276]},"n185975913":{"id":"n185975913","loc":[-85.6376323,41.9457936]},"n185975915":{"id":"n185975915","loc":[-85.6383596,41.9455425]},"n185975932":{"id":"n185975932","loc":[-85.644403,41.945088]},"n185975934":{"id":"n185975934","loc":[-85.645486,41.945084]},"n185979974":{"id":"n185979974","loc":[-85.644381,41.943831]},"n2139795809":{"id":"n2139795809","loc":[-85.6464756,41.9450813]},"n2139795810":{"id":"n2139795810","loc":[-85.6466646,41.945174]},"n2139858952":{"id":"n2139858952","loc":[-85.6383567,41.9454039]},"n2139858953":{"id":"n2139858953","loc":[-85.6380506,41.9455301]},"n2139858954":{"id":"n2139858954","loc":[-85.6377321,41.9455546]},"n2139858955":{"id":"n2139858955","loc":[-85.6376571,41.9455245]},"n2139858956":{"id":"n2139858956","loc":[-85.6375859,41.9454544]},"n2139858957":{"id":"n2139858957","loc":[-85.6376686,41.9453185]},"n2139858958":{"id":"n2139858958","loc":[-85.6378936,41.9451712]},"n2139858959":{"id":"n2139858959","loc":[-85.6379225,41.9450825]},"n2139858960":{"id":"n2139858960","loc":[-85.6379302,41.9447564]},"n2139858961":{"id":"n2139858961","loc":[-85.6379763,41.9446963]},"n2139858962":{"id":"n2139858962","loc":[-85.6380436,41.9446706]},"n2139858963":{"id":"n2139858963","loc":[-85.6381286,41.9445969]},"n2139858965":{"id":"n2139858965","loc":[-85.6382523,41.9444134]},"n2140006367":{"id":"n2140006367","loc":[-85.6380923,41.9454418]},"n2140006368":{"id":"n2140006368","loc":[-85.6384089,41.9453146]},"n2140006372":{"id":"n2140006372","loc":[-85.6383252,41.9447706]},"n2140006374":{"id":"n2140006374","loc":[-85.6381033,41.9447436]},"n2140006376":{"id":"n2140006376","loc":[-85.6379759,41.9447815]},"n2140006378":{"id":"n2140006378","loc":[-85.6379832,41.9448654]},"n2140006380":{"id":"n2140006380","loc":[-85.6380632,41.9450738]},"n2140006382":{"id":"n2140006382","loc":[-85.6380414,41.9452064]},"n2140006389":{"id":"n2140006389","loc":[-85.6379068,41.9453092]},"n2140006391":{"id":"n2140006391","loc":[-85.637925,41.9453904]},"n2140006393":{"id":"n2140006393","loc":[-85.6379977,41.94545]},"n2189123275":{"id":"n2189123275","loc":[-85.6371346,41.9462544]},"n2189123278":{"id":"n2189123278","loc":[-85.6368371,41.9466153]},"n2189123280":{"id":"n2189123280","loc":[-85.6379537,41.9489088]},"n2189123282":{"id":"n2189123282","loc":[-85.6383816,41.9497858]},"n2189123285":{"id":"n2189123285","loc":[-85.6393673,41.9512417]},"n2189123287":{"id":"n2189123287","loc":[-85.640554,41.9517766]},"n2189123289":{"id":"n2189123289","loc":[-85.6411,41.9522344]},"n2189123291":{"id":"n2189123291","loc":[-85.6417418,41.9526574]},"n2189123293":{"id":"n2189123293","loc":[-85.642321,41.9529407]},"n2189123295":{"id":"n2189123295","loc":[-85.6427697,41.9532278]},"n2189123297":{"id":"n2189123297","loc":[-85.6433332,41.9538254]},"n2189123300":{"id":"n2189123300","loc":[-85.6435785,41.9543648]},"n2189123301":{"id":"n2189123301","loc":[-85.6444394,41.9541048]},"n2189123303":{"id":"n2189123303","loc":[-85.6450603,41.954]},"n2189123312":{"id":"n2189123312","loc":[-85.6454829,41.9539108]},"n2189123314":{"id":"n2189123314","loc":[-85.6460464,41.9538526]},"n2189123315":{"id":"n2189123315","loc":[-85.6463178,41.9537167]},"n2189123316":{"id":"n2189123316","loc":[-85.646276,41.9534141]},"n2189123317":{"id":"n2189123317","loc":[-85.6459995,41.9531541]},"n2189123318":{"id":"n2189123318","loc":[-85.645222,41.9531929]},"n2189123319":{"id":"n2189123319","loc":[-85.6447316,41.9531813]},"n2189123320":{"id":"n2189123320","loc":[-85.6440637,41.9532977]},"n2189123321":{"id":"n2189123321","loc":[-85.6438185,41.9531774]},"n2189123322":{"id":"n2189123322","loc":[-85.6440011,41.9528398]},"n2189123323":{"id":"n2189123323","loc":[-85.6442672,41.9525914]},"n2189123324":{"id":"n2189123324","loc":[-85.6442881,41.9523276]},"n2189123326":{"id":"n2189123326","loc":[-85.644262,41.952153]},"n2189123328":{"id":"n2189123328","loc":[-85.6441681,41.9520404]},"n2189123330":{"id":"n2189123330","loc":[-85.6442098,41.9517494]},"n2189123333":{"id":"n2189123333","loc":[-85.6438498,41.9515864]},"n2189123336":{"id":"n2189123336","loc":[-85.6435889,41.9513225]},"n2189123339":{"id":"n2189123339","loc":[-85.6425349,41.9510315]},"n2189123342":{"id":"n2189123342","loc":[-85.6422688,41.9508802]},"n2189123345":{"id":"n2189123345","loc":[-85.6418775,41.9508142]},"n2189123348":{"id":"n2189123348","loc":[-85.6415488,41.9508064]},"n2189123351":{"id":"n2189123351","loc":[-85.6411027,41.9505488]},"n2189123353":{"id":"n2189123353","loc":[-85.6410374,41.9498208]},"n2189123355":{"id":"n2189123355","loc":[-85.6410061,41.9494327]},"n2189123357":{"id":"n2189123357","loc":[-85.6411522,41.9482569]},"n2189123359":{"id":"n2189123359","loc":[-85.6410548,41.9473036]},"n2189123368":{"id":"n2189123368","loc":[-85.6380216,41.9458974]},"n2189123370":{"id":"n2189123370","loc":[-85.6386721,41.9507782]},"w17968193":{"id":"w17968193","tags":{"highway":"residential","name":"French St"},"nodes":["n185970906","n185982877","n185967774","n185985823","n185979974"]},"w203972939":{"id":"w203972939","tags":{"highway":"path"},"nodes":["n2139858965","n2139858966"]},"w203988289":{"id":"w203988289","tags":{"area":"yes","natural":"water"},"nodes":["n2140006367","n2140006368","n2140006419","n2140006369","n2140006417","n2140006370","n2140006372","n2140006374","n2140006376","n2140006378","n2140006380","n2140006382","n2140006389","n2140006391","n2140006393","n2140006367"]},"w208640157":{"id":"w208640157","tags":{"area":"yes","natural":"wetland"},"nodes":["n1819849029","n2189123275","n2189123278","n2189123280","n2189123282","n2189123370","n2189123285","n2189123287","n2189123289","n2189123291","n2189123293","n2189123295","n2189123297","n2189123300","n2189123301","n2189123303","n2189123312","n2189123314","n2189123315","n2189123316","n2189123317","n2189123318","n2189123319","n2189123320","n2189123321","n2189123322","n2189123323","n2189123324","n2189123326","n2189123328","n2189123330","n2189123333","n2189123336","n2189123339","n2189123342","n2189123345","n2189123348","n2189123351","n2189123353","n2189123355","n2189123357","n2189123359","n2189123361","n2189123363","n2189123365","n2189123368","n1819849029"]},"w17966281":{"id":"w17966281","tags":{"highway":"residential","name":"Pealer St"},"nodes":["n185975911","n185975913","n185975915","n1475284042","n185975917","n185975919","n185975925","n185970909","n1475284013","n1475283980","n185975928","n185967775","n185975930","n185975932","n185975934","n2139795809","n2139795810"]},"w17965353":{"id":"w17965353","tags":{"highway":"residential","name":"Yauney St"},"nodes":["n185966958","n185966959","n185966960","n185966962"]},"w203972938":{"id":"w203972938","tags":{"highway":"path","name":"Riverwalk Trail"},"nodes":["n2139858964","n2139858965","n2139858963","n2139858962","n2139858961","n2139858960","n2139858959","n2139858958","n2139858957","n2139858956","n2139858955","n2139858954","n2139858953","n2139858952","n2139858951"]},"n354002665":{"id":"n354002665","loc":[-85.6366599,41.9444923],"tags":{"name":"Memory Isle","place":"island"}},"n354031301":{"id":"n354031301","loc":[-85.635,41.9463889],"tags":{"amenity":"post_office","name":"Three Rivers Post Office"}},"n185963454":{"id":"n185963454","loc":[-85.633686,41.946072]},"n185963455":{"id":"n185963455","loc":[-85.633815,41.946131]},"n185963456":{"id":"n185963456","loc":[-85.633951,41.946174]},"n185978375":{"id":"n185978375","loc":[-85.634385,41.94559]},"n185978377":{"id":"n185978377","loc":[-85.634544,41.945725]},"n185978379":{"id":"n185978379","loc":[-85.634573,41.945764]},"n185978381":{"id":"n185978381","loc":[-85.634616,41.945849]},"n185978383":{"id":"n185978383","loc":[-85.634629,41.945893]},"n185984011":{"id":"n185984011","loc":[-85.636058,41.946201]},"n185984013":{"id":"n185984013","loc":[-85.636112,41.946366]},"n185984015":{"id":"n185984015","loc":[-85.636143,41.946551]},"n185988237":{"id":"n185988237","loc":[-85.6354162,41.946044]},"n185988969":{"id":"n185988969","loc":[-85.635374,41.945325]},"n185988971":{"id":"n185988971","loc":[-85.635643,41.945585]},"n185988972":{"id":"n185988972","loc":[-85.635853,41.94586]},"n1475283992":{"id":"n1475283992","loc":[-85.6372968,41.9459007]},"n1475284011":{"id":"n1475284011","loc":[-85.6359415,41.9459797]},"n1475284019":{"id":"n1475284019","loc":[-85.6364433,41.9460423]},"n185984009":{"id":"n185984009","loc":[-85.6360524,41.9460485]},"n185988239":{"id":"n185988239","loc":[-85.6358187,41.9460423]},"n185988243":{"id":"n185988243","loc":[-85.6366156,41.9460282]},"n185988244":{"id":"n185988244","loc":[-85.6368316,41.9460046]},"n185988245":{"id":"n185988245","loc":[-85.6370133,41.9459704]},"n185988241":{"id":"n185988241","loc":[-85.636291,41.9460461]},"n185964976":{"id":"n185964976","loc":[-85.633923,41.9434157]},"n185964980":{"id":"n185964980","loc":[-85.6333656,41.9437293]},"n185978388":{"id":"n185978388","loc":[-85.6346449,41.9460571]},"n1819858504":{"id":"n1819858504","loc":[-85.6365343,41.9447926]},"n1819858506":{"id":"n1819858506","loc":[-85.6370546,41.9451882]},"n1819858516":{"id":"n1819858516","loc":[-85.6358369,41.9444654]},"n1819858519":{"id":"n1819858519","loc":[-85.6361534,41.9446176]},"n1819858525":{"id":"n1819858525","loc":[-85.6368025,41.9449442]},"n1819858527":{"id":"n1819858527","loc":[-85.6334199,41.9457495]},"n185963452":{"id":"n185963452","loc":[-85.633564,41.9458519]},"n185963453":{"id":"n185963453","loc":[-85.6336152,41.9459804]},"n185963451":{"id":"n185963451","loc":[-85.6332888,41.9456871]},"n2130304152":{"id":"n2130304152","loc":[-85.6359466,41.9454599]},"n2130304153":{"id":"n2130304153","loc":[-85.6362773,41.9452683]},"n2130304154":{"id":"n2130304154","loc":[-85.6352028,41.9442868]},"n2130304155":{"id":"n2130304155","loc":[-85.6348756,41.9444769]},"n2130304156":{"id":"n2130304156","loc":[-85.6349723,41.9444207]},"n2130304157":{"id":"n2130304157","loc":[-85.6338698,41.9434443]},"n2130304158":{"id":"n2130304158","loc":[-85.635094,41.9451026]},"n2130304160":{"id":"n2130304160","loc":[-85.6353716,41.9449322]},"n2130304162":{"id":"n2130304162","loc":[-85.6365942,41.9459352]},"n2130304163":{"id":"n2130304163","loc":[-85.6369006,41.9457469]},"n2130304164":{"id":"n2130304164","loc":[-85.6363292,41.9452278]},"n2130304165":{"id":"n2130304165","loc":[-85.6360248,41.9454175]},"n2139824683":{"id":"n2139824683","loc":[-85.6339825,41.9446441]},"n2139824689":{"id":"n2139824689","loc":[-85.6340437,41.9446925]},"n2139824702":{"id":"n2139824702","loc":[-85.6340961,41.9447551]},"n2139824705":{"id":"n2139824705","loc":[-85.6337467,41.944809]},"n2139824707":{"id":"n2139824707","loc":[-85.6341598,41.9448129]},"n2139824710":{"id":"n2139824710","loc":[-85.6342771,41.9448223]},"n2139824712":{"id":"n2139824712","loc":[-85.6346058,41.944841]},"n2139824713":{"id":"n2139824713","loc":[-85.633808,41.9448574]},"n2139824714":{"id":"n2139824714","loc":[-85.6340889,41.9448589]},"n2139824716":{"id":"n2139824716","loc":[-85.6343335,41.944871]},"n2139824717":{"id":"n2139824717","loc":[-85.6343341,41.9448717]},"n2139824720":{"id":"n2139824720","loc":[-85.6338757,41.9449069]},"n2139824721":{"id":"n2139824721","loc":[-85.6341445,41.9449071]},"n2139824724":{"id":"n2139824724","loc":[-85.6334787,41.9449262]},"n2139824726":{"id":"n2139824726","loc":[-85.6347119,41.9449332]},"n2139824727":{"id":"n2139824727","loc":[-85.6347175,41.9449418]},"n2139824728":{"id":"n2139824728","loc":[-85.6344284,41.9449538]},"n2139824729":{"id":"n2139824729","loc":[-85.6339339,41.9449573]},"n2139824730":{"id":"n2139824730","loc":[-85.6339179,41.9449682]},"n2139824732":{"id":"n2139824732","loc":[-85.6335472,41.9449895]},"n2139824733":{"id":"n2139824733","loc":[-85.6339736,41.9450164]},"n2139824735":{"id":"n2139824735","loc":[-85.6336034,41.9450415]},"n2139824736":{"id":"n2139824736","loc":[-85.6348317,41.945043]},"n2139824737":{"id":"n2139824737","loc":[-85.63403,41.9450651]},"n2139824738":{"id":"n2139824738","loc":[-85.6336611,41.9450949]},"n2139824740":{"id":"n2139824740","loc":[-85.6336582,41.9450966]},"n2139824744":{"id":"n2139824744","loc":[-85.6331702,41.9451107]},"n2139824745":{"id":"n2139824745","loc":[-85.6333388,41.9451142]},"n2139824746":{"id":"n2139824746","loc":[-85.6337131,41.9451341]},"n2139824747":{"id":"n2139824747","loc":[-85.6337021,41.9451372]},"n2139824748":{"id":"n2139824748","loc":[-85.6341244,41.9451472]},"n2139824749":{"id":"n2139824749","loc":[-85.6333952,41.945166]},"n2139824750":{"id":"n2139824750","loc":[-85.633395,41.9451661]},"n2139824751":{"id":"n2139824751","loc":[-85.6346258,41.9451725]},"n2139824752":{"id":"n2139824752","loc":[-85.6332387,41.9451741]},"n2139824753":{"id":"n2139824753","loc":[-85.6346901,41.9451853]},"n2139824754":{"id":"n2139824754","loc":[-85.6346611,41.9452035]},"n2139824755":{"id":"n2139824755","loc":[-85.6346574,41.9452059]},"n2139824756":{"id":"n2139824756","loc":[-85.6345611,41.9452133]},"n2139824757":{"id":"n2139824757","loc":[-85.633453,41.9452194]},"n2139824758":{"id":"n2139824758","loc":[-85.6335508,41.9452283]},"n2139824759":{"id":"n2139824759","loc":[-85.6347424,41.9452312]},"n2139824760":{"id":"n2139824760","loc":[-85.6342305,41.9452395]},"n2139824761":{"id":"n2139824761","loc":[-85.6342319,41.9452449]},"n2139824762":{"id":"n2139824762","loc":[-85.6334969,41.94526]},"n2139824763":{"id":"n2139824763","loc":[-85.63468,41.9452706]},"n2139824764":{"id":"n2139824764","loc":[-85.6346772,41.9452724]},"n2139824765":{"id":"n2139824765","loc":[-85.6338611,41.9452763]},"n2139824766":{"id":"n2139824766","loc":[-85.6347811,41.9452939]},"n2139824767":{"id":"n2139824767","loc":[-85.6347375,41.9453211]},"n2139824768":{"id":"n2139824768","loc":[-85.6339171,41.9453301]},"n2139824769":{"id":"n2139824769","loc":[-85.6348307,41.9453377]},"n2139824770":{"id":"n2139824770","loc":[-85.6347067,41.9453405]},"n2139824771":{"id":"n2139824771","loc":[-85.6343461,41.9453461]},"n2139824772":{"id":"n2139824772","loc":[-85.6343481,41.9453475]},"n2139824773":{"id":"n2139824773","loc":[-85.634805,41.9453538]},"n2139824774":{"id":"n2139824774","loc":[-85.6336997,41.9453692]},"n2139824775":{"id":"n2139824775","loc":[-85.6339709,41.9453818]},"n2139824776":{"id":"n2139824776","loc":[-85.6336229,41.9454134]},"n2139824777":{"id":"n2139824777","loc":[-85.6349022,41.9454141]},"n2139824778":{"id":"n2139824778","loc":[-85.6348854,41.9454246]},"n2139824779":{"id":"n2139824779","loc":[-85.6340286,41.9454373]},"n2139824780":{"id":"n2139824780","loc":[-85.6336963,41.9454572]},"n2139824781":{"id":"n2139824781","loc":[-85.6336789,41.9454672]},"n2139824782":{"id":"n2139824782","loc":[-85.6344933,41.945475]},"n2139824783":{"id":"n2139824783","loc":[-85.6340854,41.9454918]},"n2139824784":{"id":"n2139824784","loc":[-85.6350036,41.9455034]},"n2139824785":{"id":"n2139824785","loc":[-85.6337501,41.9455089]},"n2139824786":{"id":"n2139824786","loc":[-85.6337497,41.9455091]},"n2139824787":{"id":"n2139824787","loc":[-85.6345425,41.9455186]},"n2139824788":{"id":"n2139824788","loc":[-85.6341459,41.9455372]},"n2139824789":{"id":"n2139824789","loc":[-85.6341376,41.945542]},"n2139824790":{"id":"n2139824790","loc":[-85.6338394,41.9455462]},"n2139824791":{"id":"n2139824791","loc":[-85.6349171,41.9455588]},"n2139824792":{"id":"n2139824792","loc":[-85.6338074,41.9455646]},"n2139824793":{"id":"n2139824793","loc":[-85.6346229,41.9455894]},"n2139824794":{"id":"n2139824794","loc":[-85.6338983,41.9455995]},"n2139824795":{"id":"n2139824795","loc":[-85.6338962,41.9456007]},"n2139824796":{"id":"n2139824796","loc":[-85.6342475,41.9456348]},"n2139824797":{"id":"n2139824797","loc":[-85.6339505,41.9456497]},"n2139824798":{"id":"n2139824798","loc":[-85.6347243,41.9456788]},"n2139824799":{"id":"n2139824799","loc":[-85.635057,41.9456831]},"n2139824800":{"id":"n2139824800","loc":[-85.635287,41.9457056]},"n2139824801":{"id":"n2139824801","loc":[-85.6350753,41.9457068]},"n2139824802":{"id":"n2139824802","loc":[-85.6347753,41.9457252]},"n2139824803":{"id":"n2139824803","loc":[-85.6340521,41.9457473]},"n2139824804":{"id":"n2139824804","loc":[-85.6352875,41.9457611]},"n2139824805":{"id":"n2139824805","loc":[-85.6352941,41.9457611]},"n2139824806":{"id":"n2139824806","loc":[-85.6350758,41.9457623]},"n2139824807":{"id":"n2139824807","loc":[-85.6348194,41.9457638]},"n2139824808":{"id":"n2139824808","loc":[-85.635296,41.9459428]},"n2139824809":{"id":"n2139824809","loc":[-85.6348212,41.9459455]},"n2139832635":{"id":"n2139832635","loc":[-85.6354612,41.9448791]},"n2139832636":{"id":"n2139832636","loc":[-85.6360241,41.9453844]},"n2139832637":{"id":"n2139832637","loc":[-85.6361452,41.9453121]},"n2139832639":{"id":"n2139832639","loc":[-85.6355997,41.944797]},"n2139832641":{"id":"n2139832641","loc":[-85.6351346,41.9443541]},"n2139832647":{"id":"n2139832647","loc":[-85.6329883,41.9453692]},"n2139832653":{"id":"n2139832653","loc":[-85.6333643,41.9456293]},"n2139832663":{"id":"n2139832663","loc":[-85.6335394,41.9455339]},"n2139832665":{"id":"n2139832665","loc":[-85.6332375,41.9452476]},"n2139832667":{"id":"n2139832667","loc":[-85.6331664,41.9452161]},"n2139832669":{"id":"n2139832669","loc":[-85.6331144,41.9451875]},"n2139832671":{"id":"n2139832671","loc":[-85.6330779,41.9451274]},"n2139832673":{"id":"n2139832673","loc":[-85.6330664,41.9450802]},"n2139832678":{"id":"n2139832678","loc":[-85.6332218,41.9453585]},"n2139832686":{"id":"n2139832686","loc":[-85.6334246,41.945541]},"n2139832691":{"id":"n2139832691","loc":[-85.6329898,41.9454997]},"n2139832693":{"id":"n2139832693","loc":[-85.6343554,41.9443274]},"n2139832694":{"id":"n2139832694","loc":[-85.6336339,41.9437089]},"n2139832696":{"id":"n2139832696","loc":[-85.633532,41.9437708]},"n2139832697":{"id":"n2139832697","loc":[-85.6338316,41.9440868]},"n2139832698":{"id":"n2139832698","loc":[-85.6342258,41.9444141]},"n2139832699":{"id":"n2139832699","loc":[-85.6339164,41.9442166]},"n2139832700":{"id":"n2139832700","loc":[-85.6341389,41.944384]},"n2139832701":{"id":"n2139832701","loc":[-85.634235,41.9443259]},"n2139832702":{"id":"n2139832702","loc":[-85.633613,41.9437875]},"n2139832703":{"id":"n2139832703","loc":[-85.633915,41.9436132]},"n2139832704":{"id":"n2139832704","loc":[-85.6340019,41.9435613]},"n2139832706":{"id":"n2139832706","loc":[-85.6343197,41.9438427]},"n2139832708":{"id":"n2139832708","loc":[-85.6342361,41.9438936]},"n2139832709":{"id":"n2139832709","loc":[-85.6353839,41.9460401]},"n2139832710":{"id":"n2139832710","loc":[-85.6354032,41.9456763]},"n2139832711":{"id":"n2139832711","loc":[-85.6356839,41.9459252]},"n2139832712":{"id":"n2139832712","loc":[-85.6356109,41.945735]},"n2139832713":{"id":"n2139832713","loc":[-85.6353997,41.9457421]},"n2139832714":{"id":"n2139832714","loc":[-85.6353895,41.9459347]},"n2139832715":{"id":"n2139832715","loc":[-85.6334777,41.9436628]},"n2139832716":{"id":"n2139832716","loc":[-85.6333137,41.9435382]},"n2139832717":{"id":"n2139832717","loc":[-85.6330938,41.9435406]},"n2139832721":{"id":"n2139832721","loc":[-85.6333023,41.9434922]},"n2139832722":{"id":"n2139832722","loc":[-85.6330466,41.943623]},"n2139832723":{"id":"n2139832723","loc":[-85.6332746,41.9435624]},"n2139832724":{"id":"n2139832724","loc":[-85.6333511,41.9435176]},"n2139832725":{"id":"n2139832725","loc":[-85.6332241,41.9434001]},"n2139832726":{"id":"n2139832726","loc":[-85.6332355,41.9433686]},"n2139870373":{"id":"n2139870373","loc":[-85.6351783,41.9439117]},"n2139870374":{"id":"n2139870374","loc":[-85.6351431,41.9439217]},"n2139870375":{"id":"n2139870375","loc":[-85.6348853,41.9439117]},"n2139870376":{"id":"n2139870376","loc":[-85.6348317,41.9439105]},"n2139870377":{"id":"n2139870377","loc":[-85.6346384,41.944007]},"n2139870378":{"id":"n2139870378","loc":[-85.6345563,41.9440523]},"n2140006403":{"id":"n2140006403","loc":[-85.6359942,41.9450097]},"n2140006405":{"id":"n2140006405","loc":[-85.6363884,41.9446079]},"n2140006407":{"id":"n2140006407","loc":[-85.6362148,41.9447874]},"n2140006409":{"id":"n2140006409","loc":[-85.6379476,41.9445869]},"n2140006411":{"id":"n2140006411","loc":[-85.6378485,41.9445674]},"n2140006413":{"id":"n2140006413","loc":[-85.6378952,41.9444547]},"n2140006415":{"id":"n2140006415","loc":[-85.6379962,41.944477]},"n2140006421":{"id":"n2140006421","loc":[-85.6355248,41.9433702]},"n2140006423":{"id":"n2140006423","loc":[-85.6378471,41.9439233]},"n2140006425":{"id":"n2140006425","loc":[-85.6378913,41.9441238]},"n2140006426":{"id":"n2140006426","loc":[-85.6381674,41.9442289]},"n2140006427":{"id":"n2140006427","loc":[-85.6382359,41.9440975]},"n2140006428":{"id":"n2140006428","loc":[-85.6382071,41.9440252]},"n2140006429":{"id":"n2140006429","loc":[-85.6381409,41.9439973]},"n2140006430":{"id":"n2140006430","loc":[-85.6380569,41.9440153]},"n2140006433":{"id":"n2140006433","loc":[-85.6379071,41.9442467]},"n2140006435":{"id":"n2140006435","loc":[-85.6381634,41.9443125]},"n2140006436":{"id":"n2140006436","loc":[-85.6382407,41.944301]},"n2140006438":{"id":"n2140006438","loc":[-85.6382761,41.9442188]},"n2140006439":{"id":"n2140006439","loc":[-85.6382429,41.9441761]},"n2140006440":{"id":"n2140006440","loc":[-85.6382016,41.9441632]},"n2140006441":{"id":"n2140006441","loc":[-85.6378185,41.9439835]},"n2166205688":{"id":"n2166205688","loc":[-85.6349963,41.9444392]},"n2168544780":{"id":"n2168544780","loc":[-85.633944,41.945807]},"n2168544781":{"id":"n2168544781","loc":[-85.6340783,41.9458621]},"n2168544782":{"id":"n2168544782","loc":[-85.6338184,41.9457548]},"n2168544783":{"id":"n2168544783","loc":[-85.6339925,41.9459777]},"n2168544784":{"id":"n2168544784","loc":[-85.6337317,41.9458698]},"n2168544785":{"id":"n2168544785","loc":[-85.6337297,41.9460042]},"n2168544786":{"id":"n2168544786","loc":[-85.633919,41.9460797]},"n2168544787":{"id":"n2168544787","loc":[-85.6338672,41.9459263]},"n2168544788":{"id":"n2168544788","loc":[-85.6338246,41.9459853]},"n2168544789":{"id":"n2168544789","loc":[-85.6337615,41.9459601]},"n2168544790":{"id":"n2168544790","loc":[-85.6342079,41.9460399]},"n2168544791":{"id":"n2168544791","loc":[-85.6343346,41.9458503]},"n2168544792":{"id":"n2168544792","loc":[-85.6343759,41.9458116]},"n2168544793":{"id":"n2168544793","loc":[-85.6344394,41.9458109]},"n2168544795":{"id":"n2168544795","loc":[-85.6344827,41.945851]},"n2168544797":{"id":"n2168544797","loc":[-85.6344807,41.945969]},"n2168544798":{"id":"n2168544798","loc":[-85.6344404,41.9459697]},"n2168544799":{"id":"n2168544799","loc":[-85.6344413,41.9460333]},"n2168544800":{"id":"n2168544800","loc":[-85.6342173,41.9460705]},"n2168544801":{"id":"n2168544801","loc":[-85.6342162,41.9460392]},"n2168544802":{"id":"n2168544802","loc":[-85.6344251,41.9460351]},"n2168544805":{"id":"n2168544805","loc":[-85.6344257,41.9460507]},"n2168544807":{"id":"n2168544807","loc":[-85.6344721,41.9460498]},"n2168544809":{"id":"n2168544809","loc":[-85.6344754,41.9461427]},"n2168544811":{"id":"n2168544811","loc":[-85.6344311,41.9461435]},"n2168544813":{"id":"n2168544813","loc":[-85.6344317,41.9461592]},"n2168544815":{"id":"n2168544815","loc":[-85.6343708,41.9461604]},"n2168544817":{"id":"n2168544817","loc":[-85.6343715,41.9461786]},"n2168544819":{"id":"n2168544819","loc":[-85.6343229,41.9461795]},"n2168544821":{"id":"n2168544821","loc":[-85.6343222,41.9461606]},"n2168544823":{"id":"n2168544823","loc":[-85.6342476,41.9461621]},"n2168544825":{"id":"n2168544825","loc":[-85.6342444,41.94607]},"n2168544827":{"id":"n2168544827","loc":[-85.634138,41.9461632]},"n2168544829":{"id":"n2168544829","loc":[-85.6342016,41.9460703]},"n2168544830":{"id":"n2168544830","loc":[-85.6332929,41.9463092]},"n2168544831":{"id":"n2168544831","loc":[-85.633122,41.946239]},"n2168544832":{"id":"n2168544832","loc":[-85.6332954,41.9460055]},"n2168544833":{"id":"n2168544833","loc":[-85.6333954,41.9460466]},"n2168544834":{"id":"n2168544834","loc":[-85.6334044,41.9460345]},"n2168544835":{"id":"n2168544835","loc":[-85.6334594,41.9460571]},"n2168544836":{"id":"n2168544836","loc":[-85.6333871,41.9461544]},"n2168544837":{"id":"n2168544837","loc":[-85.633403,41.9461609]},"n2168544838":{"id":"n2168544838","loc":[-85.6341683,41.9464167]},"n2168544839":{"id":"n2168544839","loc":[-85.6341711,41.9463411]},"n2168544840":{"id":"n2168544840","loc":[-85.6344471,41.9463469]},"n2168544841":{"id":"n2168544841","loc":[-85.6344441,41.9464243]},"n2168544842":{"id":"n2168544842","loc":[-85.6343622,41.9464226]},"n2168544843":{"id":"n2168544843","loc":[-85.6343593,41.9464989]},"n2168544844":{"id":"n2168544844","loc":[-85.6342812,41.9464973]},"n2168544845":{"id":"n2168544845","loc":[-85.634283,41.9464504]},"n2168544846":{"id":"n2168544846","loc":[-85.6342609,41.9464499]},"n2168544847":{"id":"n2168544847","loc":[-85.6342621,41.9464187]},"n2168544848":{"id":"n2168544848","loc":[-85.6348414,41.9463396]},"n2168544849":{"id":"n2168544849","loc":[-85.6348387,41.9461872]},"n2168544850":{"id":"n2168544850","loc":[-85.6351186,41.9461844]},"n2168544851":{"id":"n2168544851","loc":[-85.635119,41.9462112]},"n2168544852":{"id":"n2168544852","loc":[-85.6351918,41.9462104]},"n2168544853":{"id":"n2168544853","loc":[-85.6351944,41.9463515]},"n2168544854":{"id":"n2168544854","loc":[-85.6351049,41.9463524]},"n2168544855":{"id":"n2168544855","loc":[-85.6351046,41.946337]},"n2189153180":{"id":"n2189153180","loc":[-85.6340369,41.9469572]},"n2189153181":{"id":"n2189153181","loc":[-85.6342531,41.946953]},"n2189153183":{"id":"n2189153183","loc":[-85.6348115,41.9465468]},"n2189153184":{"id":"n2189153184","loc":[-85.6348105,41.9464569]},"n2189153185":{"id":"n2189153185","loc":[-85.6351431,41.9464549]},"n2189153186":{"id":"n2189153186","loc":[-85.6351441,41.9465448]},"n2189153187":{"id":"n2189153187","loc":[-85.6350077,41.9465456]},"n2189153188":{"id":"n2189153188","loc":[-85.635008,41.9465721]},"n2189153189":{"id":"n2189153189","loc":[-85.6348965,41.9465727]},"n2189153190":{"id":"n2189153190","loc":[-85.6348962,41.9465463]},"n2189153191":{"id":"n2189153191","loc":[-85.6348963,41.9471586]},"n2189153192":{"id":"n2189153192","loc":[-85.6348944,41.947032]},"n2189153193":{"id":"n2189153193","loc":[-85.6350241,41.947031]},"n2189153194":{"id":"n2189153194","loc":[-85.635026,41.9471575]},"n2189153195":{"id":"n2189153195","loc":[-85.6352328,41.9471053]},"n2189153196":{"id":"n2189153196","loc":[-85.6352359,41.9469906]},"n2189153197":{"id":"n2189153197","loc":[-85.6353694,41.9469925]},"n2189153198":{"id":"n2189153198","loc":[-85.6353664,41.9471072]},"n2189153199":{"id":"n2189153199","loc":[-85.6348241,41.9469287]},"n2189153200":{"id":"n2189153200","loc":[-85.6348248,41.9468185]},"n2189153201":{"id":"n2189153201","loc":[-85.6351199,41.9468195]},"n2189153202":{"id":"n2189153202","loc":[-85.6351192,41.9469298]},"n2189153203":{"id":"n2189153203","loc":[-85.6347965,41.9468057]},"n2189153204":{"id":"n2189153204","loc":[-85.634792,41.9466044]},"n2189153205":{"id":"n2189153205","loc":[-85.6349483,41.9466025]},"n2189153206":{"id":"n2189153206","loc":[-85.6349493,41.9466448]},"n2189153207":{"id":"n2189153207","loc":[-85.6349753,41.9466445]},"n2189153208":{"id":"n2189153208","loc":[-85.6349743,41.9465995]},"n2189153209":{"id":"n2189153209","loc":[-85.6351173,41.9465977]},"n2189153210":{"id":"n2189153210","loc":[-85.6351219,41.9468015]},"n2189153211":{"id":"n2189153211","loc":[-85.6349806,41.9468032]},"n2189153212":{"id":"n2189153212","loc":[-85.6349794,41.9467519]},"n2189153213":{"id":"n2189153213","loc":[-85.6349521,41.9467523]},"n2189153214":{"id":"n2189153214","loc":[-85.6349532,41.9468037]},"n2189153215":{"id":"n2189153215","loc":[-85.6346302,41.9468381]},"n2189153216":{"id":"n2189153216","loc":[-85.6343028,41.9468449]},"n2189153217":{"id":"n2189153217","loc":[-85.6342006,41.9468297]},"n2189153218":{"id":"n2189153218","loc":[-85.6336698,41.9465918]},"n2189153219":{"id":"n2189153219","loc":[-85.6344663,41.9466639]},"n2189153220":{"id":"n2189153220","loc":[-85.6344639,41.9466015]},"n2189153221":{"id":"n2189153221","loc":[-85.6342283,41.9466065]},"n2189153222":{"id":"n2189153222","loc":[-85.6342303,41.9466587]},"n2189153223":{"id":"n2189153223","loc":[-85.6342843,41.9466575]},"n2189153224":{"id":"n2189153224","loc":[-85.6342851,41.9466794]},"n2189153225":{"id":"n2189153225","loc":[-85.6343475,41.9466781]},"n2189153226":{"id":"n2189153226","loc":[-85.634347,41.9466664]},"n2189153227":{"id":"n2189153227","loc":[-85.6354428,41.9470148]},"n2189153228":{"id":"n2189153228","loc":[-85.6354432,41.9468005]},"n2189153229":{"id":"n2189153229","loc":[-85.6360277,41.9468011]},"n2189153230":{"id":"n2189153230","loc":[-85.6360273,41.9470154]},"n2189153231":{"id":"n2189153231","loc":[-85.6354565,41.9465823]},"n2189153232":{"id":"n2189153232","loc":[-85.6354496,41.946218]},"n2189153233":{"id":"n2189153233","loc":[-85.6356355,41.9465788]},"n2189153234":{"id":"n2189153234","loc":[-85.6357155,41.9468008]},"n2189153235":{"id":"n2189153235","loc":[-85.6359539,41.9467969]},"n2189153236":{"id":"n2189153236","loc":[-85.6359561,41.9463036]},"n2189153237":{"id":"n2189153237","loc":[-85.6360129,41.9464793]},"n2189153238":{"id":"n2189153238","loc":[-85.6360152,41.9463898]},"n2189153239":{"id":"n2189153239","loc":[-85.6359607,41.9464928]},"n2189153240":{"id":"n2189153240","loc":[-85.6356903,41.9462227]},"n2189153242":{"id":"n2189153242","loc":[-85.6354163,41.946142]},"n2189153243":{"id":"n2189153243","loc":[-85.6357546,41.9462214]},"n2189153244":{"id":"n2189153244","loc":[-85.6357937,41.9462542]},"n2189153245":{"id":"n2189153245","loc":[-85.6358723,41.9467048]},"n2189153246":{"id":"n2189153246","loc":[-85.6361494,41.946757]},"n2189153247":{"id":"n2189153247","loc":[-85.6354173,41.9469082]},"n2189153248":{"id":"n2189153248","loc":[-85.635443,41.9469079]},"n2189153249":{"id":"n2189153249","loc":[-85.6360275,41.9469093]},"n2189153250":{"id":"n2189153250","loc":[-85.6361542,41.946915]},"n2189153251":{"id":"n2189153251","loc":[-85.6358654,41.9464843]},"n2189153252":{"id":"n2189153252","loc":[-85.6359549,41.9467499]},"n2189153253":{"id":"n2189153253","loc":[-85.6357172,41.9466335]},"n2189153254":{"id":"n2189153254","loc":[-85.6355644,41.9461768]},"n2189153255":{"id":"n2189153255","loc":[-85.6355655,41.946528]},"n2189153256":{"id":"n2189153256","loc":[-85.6357055,41.9465971]},"n2189153257":{"id":"n2189153257","loc":[-85.635869,41.9465971]},"n2189153259":{"id":"n2189153259","loc":[-85.6354561,41.9470278]},"n2189153260":{"id":"n2189153260","loc":[-85.6357961,41.9470233]},"n2189153261":{"id":"n2189153261","loc":[-85.6357977,41.9470907]},"n2189153262":{"id":"n2189153262","loc":[-85.6357297,41.9470916]},"n2189153263":{"id":"n2189153263","loc":[-85.635733,41.947233]},"n2189153264":{"id":"n2189153264","loc":[-85.6362674,41.9468637]},"n2189153265":{"id":"n2189153265","loc":[-85.6362646,41.9467047]},"n2189153266":{"id":"n2189153266","loc":[-85.6363267,41.9467047]},"n2189153267":{"id":"n2189153267","loc":[-85.6362633,41.9465848]},"n2189153268":{"id":"n2189153268","loc":[-85.6363805,41.9465468]},"n2189153269":{"id":"n2189153269","loc":[-85.6364604,41.9466842]},"n2189153270":{"id":"n2189153270","loc":[-85.6364604,41.9468647]},"n2199109756":{"id":"n2199109756","loc":[-85.6337134,41.9471841]},"n2199109757":{"id":"n2199109757","loc":[-85.6336514,41.94716]},"n2199109758":{"id":"n2199109758","loc":[-85.6337043,41.9470847]},"n2199109759":{"id":"n2199109759","loc":[-85.6335997,41.9470441]},"n2199109760":{"id":"n2199109760","loc":[-85.6335064,41.9471771]},"n185960195":{"id":"n185960195","loc":[-85.6295992,41.9524346]},"n185960796":{"id":"n185960796","loc":[-85.634723,41.953681]},"n185961396":{"id":"n185961396","loc":[-85.634767,41.959009]},"n185962625":{"id":"n185962625","loc":[-85.635175,41.97201]},"n185964982":{"id":"n185964982","loc":[-85.632799,41.9440543]},"n185965289":{"id":"n185965289","loc":[-85.634621,41.947323]},"n185965291":{"id":"n185965291","loc":[-85.636166,41.947296]},"n185965399":{"id":"n185965399","loc":[-85.634776,41.959834]},"n185966937":{"id":"n185966937","loc":[-85.633183,41.947315]},"n185966948":{"id":"n185966948","loc":[-85.626406,41.957188]},"n185967422":{"id":"n185967422","loc":[-85.6320229,41.9490123]},"n185967917":{"id":"n185967917","loc":[-85.634763,41.958292]},"n185967918":{"id":"n185967918","loc":[-85.636271,41.958311]},"n185968100":{"id":"n185968100","loc":[-85.630835,41.950656]},"n185970515":{"id":"n185970515","loc":[-85.634832,41.963866]},"n185971578":{"id":"n185971578","loc":[-85.634641,41.948627]},"n185971580":{"id":"n185971580","loc":[-85.6361818,41.9486135]},"n185971631":{"id":"n185971631","loc":[-85.634729,41.954667]},"n185971632":{"id":"n185971632","loc":[-85.636236,41.954656]},"n185972155":{"id":"n185972155","loc":[-85.623333,41.961987]},"n185974583":{"id":"n185974583","loc":[-85.634686,41.951158]},"n185974585":{"id":"n185974585","loc":[-85.6362059,41.9511457]},"n185975064":{"id":"n185975064","loc":[-85.636218,41.953667]},"n185975735":{"id":"n185975735","loc":[-85.634923,41.969269]},"n185978390":{"id":"n185978390","loc":[-85.634668,41.949875]},"n185978392":{"id":"n185978392","loc":[-85.634686,41.952415]},"n185978394":{"id":"n185978394","loc":[-85.634726,41.955921]},"n185978399":{"id":"n185978399","loc":[-85.6347861,41.9606613]},"n185978402":{"id":"n185978402","loc":[-85.634806,41.961485]},"n185978406":{"id":"n185978406","loc":[-85.6348298,41.964783]},"n185978410":{"id":"n185978410","loc":[-85.6348766,41.9677088]},"n185978414":{"id":"n185978414","loc":[-85.634938,41.971566]},"n185978415":{"id":"n185978415","loc":[-85.634942,41.971611]},"n185978417":{"id":"n185978417","loc":[-85.634952,41.971655]},"n185978419":{"id":"n185978419","loc":[-85.634989,41.971741]},"n185978420":{"id":"n185978420","loc":[-85.635063,41.971864]},"n185978787":{"id":"n185978787","loc":[-85.627936,41.954693]},"n185978790":{"id":"n185978790","loc":[-85.626832,41.954677]},"n185978967":{"id":"n185978967","loc":[-85.632278,41.948613]},"n185980735":{"id":"n185980735","loc":[-85.628639,41.953725]},"n185982163":{"id":"n185982163","loc":[-85.636233,41.952398]},"n185982193":{"id":"n185982193","loc":[-85.6313855,41.9499125]},"n185982195":{"id":"n185982195","loc":[-85.6304857,41.9511945]},"n185982196":{"id":"n185982196","loc":[-85.626336,41.957291]},"n185982197":{"id":"n185982197","loc":[-85.625578,41.958664]},"n185982198":{"id":"n185982198","loc":[-85.624619,41.960145]},"n185982200":{"id":"n185982200","loc":[-85.624494,41.960338]},"n185984017":{"id":"n185984017","loc":[-85.636163,41.947382]},"n185984020":{"id":"n185984020","loc":[-85.636188,41.9498803]},"n185984022":{"id":"n185984022","loc":[-85.636276,41.955919]},"n185984024":{"id":"n185984024","loc":[-85.636279,41.956901]},"n185988036":{"id":"n185988036","loc":[-85.631422,41.948294]},"n185988867":{"id":"n185988867","loc":[-85.63102,41.948805]},"n185988869":{"id":"n185988869","loc":[-85.630773,41.949209]},"n185988871":{"id":"n185988871","loc":[-85.63005,41.95016]},"n185988872":{"id":"n185988872","loc":[-85.629423,41.951016]},"n185988873":{"id":"n185988873","loc":[-85.629252,41.951256]},"n185988875":{"id":"n185988875","loc":[-85.629126,41.951489]},"n185988877":{"id":"n185988877","loc":[-85.628991,41.951704]},"n185988878":{"id":"n185988878","loc":[-85.628689,41.952112]},"n185988879":{"id":"n185988879","loc":[-85.628313,41.952666]},"n185988880":{"id":"n185988880","loc":[-85.627687,41.953529]},"n185988882":{"id":"n185988882","loc":[-85.627394,41.953947]},"n185988884":{"id":"n185988884","loc":[-85.627287,41.954128]},"n1819858502":{"id":"n1819858502","loc":[-85.6328435,41.9455473]},"n1819858510":{"id":"n1819858510","loc":[-85.6324841,41.9453438]},"n1819858515":{"id":"n1819858515","loc":[-85.6318511,41.9446409]},"n1819858520":{"id":"n1819858520","loc":[-85.6326558,41.9454708]},"n1819858522":{"id":"n1819858522","loc":[-85.6319048,41.9447407]},"n1819858524":{"id":"n1819858524","loc":[-85.6317718,41.9443666]},"n1819858530":{"id":"n1819858530","loc":[-85.632055,41.9449128]},"n2139795768":{"id":"n2139795768","loc":[-85.6243023,41.9606102]},"n2139832645":{"id":"n2139832645","loc":[-85.6324455,41.9448607]},"n2139832649":{"id":"n2139832649","loc":[-85.6328043,41.9454773]},"n2139832651":{"id":"n2139832651","loc":[-85.6322547,41.9449621]},"n2139832675":{"id":"n2139832675","loc":[-85.6327356,41.944757]},"n2139832677":{"id":"n2139832677","loc":[-85.6325433,41.9448599]},"n2139832680":{"id":"n2139832680","loc":[-85.6328885,41.9455614]},"n2139832682":{"id":"n2139832682","loc":[-85.6320913,41.9449492]},"n2139832684":{"id":"n2139832684","loc":[-85.6325366,41.9447133]},"n2139832688":{"id":"n2139832688","loc":[-85.6322786,41.94485]},"n2139832718":{"id":"n2139832718","loc":[-85.6327486,41.9432475]},"n2139832719":{"id":"n2139832719","loc":[-85.6327926,41.9431773]},"n2139832720":{"id":"n2139832720","loc":[-85.6329033,41.943153]},"n2139832727":{"id":"n2139832727","loc":[-85.6328975,41.9430783]},"n2139844839":{"id":"n2139844839","loc":[-85.6326261,41.9432308]},"n2189015992":{"id":"n2189015992","loc":[-85.6347706,41.9593383]},"n2189153179":{"id":"n2189153179","loc":[-85.6340476,41.9472565]},"n2189153182":{"id":"n2189153182","loc":[-85.6342638,41.9472522]},"n2189153241":{"id":"n2189153241","loc":[-85.6354184,41.9473091]},"n2189153258":{"id":"n2189153258","loc":[-85.6354611,41.9472366]},"n2189153277":{"id":"n2189153277","loc":[-85.6328948,41.9462374]},"n2199109755":{"id":"n2199109755","loc":[-85.6336729,41.9472417]},"w203970139":{"id":"w203970139","tags":{"building":"yes"},"nodes":["n2139824793","n2139824787","n2139824773","n2139824778","n2139824793"]},"w203970098":{"id":"w203970098","tags":{"building":"yes"},"nodes":["n2139824748","n2139824712","n2139824726","n2139824760","n2139824748"]},"w208643132":{"id":"w208643132","tags":{"area":"yes","building":"yes"},"nodes":["n2189153195","n2189153196","n2189153197","n2189153198","n2189153195"]},"w203970094":{"id":"w203970094","tags":{"building":"yes"},"nodes":["n2139824755","n2139824753","n2139824759","n2139824764","n2139824763","n2139824767","n2139824770","n2139824782","n2139824772","n2139824756","n2139824751","n2139824754","n2139824755"]},"w208643138":{"id":"w208643138","tags":{"amenity":"parking","area":"yes"},"nodes":["n2189153231","n2189153232","n2189153240","n2189153244","n2189153236","n2189153238","n2189153237","n2189153239","n2189153252","n2189153235","n2189153234","n2189153253","n2189153233","n2189153231"]},"w203970125":{"id":"w203970125","tags":{"building":"yes"},"nodes":["n2139824735","n2139824738","n2139824757","n2139824749","n2139824735"]},"w170848823":{"id":"w170848823","tags":{"name":"Rocky River","waterway":"river"},"nodes":["n1819849189","n1819858516","n1819858519","n1819858504","n1819858525","n1819858506","n1819858513"]},"w203970898":{"id":"w203970898","tags":{"amenity":"parking","area":"yes"},"nodes":["n2139832645","n2139832647","n2139832649","n2139832651","n2139832645"]},"w203970134":{"id":"w203970134","tags":{"building":"yes"},"nodes":["n2139824796","n2139824803","n2139824797","n2139824788","n2139824796"]},"w203970104":{"id":"w203970104","tags":{"building":"yes"},"nodes":["n2139824733","n2139824730","n2139824714","n2139824721","n2139824733"]},"w206805245":{"id":"w206805245","tags":{"area":"yes","building":"yes"},"nodes":["n2168544780","n2168544781","n2139824796","n2139824803","n2168544780"]},"w206805252":{"id":"w206805252","tags":{"area":"yes","building":"yes"},"nodes":["n2168544838","n2168544839","n2168544840","n2168544841","n2168544842","n2168544843","n2168544844","n2168544845","n2168544846","n2168544847","n2168544838"]},"w203970099":{"id":"w203970099","tags":{"building":"yes"},"nodes":["n2139824783","n2139824795","n2139824790","n2139824779","n2139824783"]},"w17967730":{"id":"w17967730","tags":{"highway":"residential","name":"Water St"},"nodes":["n185963451","n2189153277","n185988036","n185988867","n185988869","n185988871","n185988872","n185988873","n185988875","n185988877","n185988878","n185988879","n185988880","n185988882","n185988884","n185978790"]},"w208643133":{"id":"w208643133","tags":{"area":"yes","building":"yes"},"nodes":["n2189153199","n2189153200","n2189153201","n2189153202","n2189153199"]},"w203970127":{"id":"w203970127","tags":{"building":"yes"},"nodes":["n2139824794","n2139824783","n2139824789","n2139824797","n2139824794"]},"w208643139":{"id":"w208643139","tags":{"highway":"service"},"nodes":["n185988237","n2189153242","n2189153247","n2189153241"]},"w203988297":{"id":"w203988297","tags":{"amenity":"parking","area":"yes"},"nodes":["n2140006423","n2140006441","n2140006425","n2140006426","n2140006440","n2140006427","n2140006428","n2140006429","n2140006430","n2140006423"]},"w206805250":{"id":"w206805250","tags":{"area":"yes","building":"yes"},"nodes":["n2168544827","n2168544823","n2168544825","n2168544800","n2168544829","n2168544827"]},"w208643140":{"id":"w208643140","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2189153242","n2189153254","n2189153243","n2189153244","n2189153251","n2189153257","n2189153245","n2189153252","n2189153246"]},"w203974055":{"id":"w203974055","tags":{"bridge":"yes","highway":"path","name":"Riverwalk Trail"},"nodes":["n2139870376","n2139870377"]},"w206805247":{"id":"w206805247","tags":{"area":"yes","building":"yes"},"nodes":["n2168544785","n2168544786","n2168544783","n2168544787","n2168544788","n2168544789","n2168544785"]},"w17964996":{"id":"w17964996","tags":{"highway":"residential","name":"Foster St"},"nodes":["n1819858524","n1819858515","n1819858522","n1819858530","n2139832682","n1819858510","n1819858520","n1819858502","n2139832680","n185963451","n1819858527","n185963452","n185963453","n185963454","n185963455","n185963456"]},"w208643144":{"id":"w208643144","tags":{"area":"yes","building":"yes"},"nodes":["n2189153264","n2189153265","n2189153266","n2189153267","n2189153268","n2189153269","n2189153270","n2189153264"]},"w203970914":{"id":"w203970914","tags":{"amenity":"parking","area":"yes"},"nodes":["n2139832722","n2139832723","n2139832724","n2139832725","n2139832726","n2139832727","n2139844839","n2139832722"]},"w208643143":{"id":"w208643143","tags":{"area":"yes","building":"yes"},"nodes":["n2189153258","n2189153259","n2189153260","n2189153261","n2189153262","n2189153263","n2189153258"]},"w203049590":{"id":"w203049590","tags":{"amenity":"parking","area":"yes"},"nodes":["n2130304152","n2130304153","n2140006403","n2130304154","n2130304156","n2130304155","n2130304160","n2130304152"]},"w203974054":{"id":"w203974054","tags":{"highway":"path","name":"Riverwalk Trail"},"nodes":["n2139858971","n2139870373","n2139870374"]},"w203049595":{"id":"w203049595","tags":{"highway":"service"},"nodes":["n2130304158","n2130304159","n2130304160","n2139832635","n2139832639"]},"w203970913":{"id":"w203970913","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2139832715","n2139832716","n2139832717","n2139832718","n2139832719","n2139832720","n2139832721","n2139832716"]},"w208643134":{"id":"w208643134","tags":{"area":"yes","building":"yes"},"nodes":["n2189153203","n2189153204","n2189153205","n2189153206","n2189153207","n2189153208","n2189153209","n2189153210","n2189153211","n2189153212","n2189153213","n2189153214","n2189153203"]},"w134150808":{"id":"w134150808","tags":{"bridge":"yes","highway":"residential","name":"Moore St"},"nodes":["n185988239","n185984009","n185988241","n1475284019"]},"w203970115":{"id":"w203970115","tags":{"building":"yes"},"nodes":["n2139824761","n2139824727","n2139824736","n2139824771","n2139824761"]},"w208643130":{"id":"w208643130","tags":{"area":"yes","building":"yes"},"nodes":["n2189153183","n2189153184","n2189153185","n2189153186","n2189153187","n2189153188","n2189153189","n2189153190","n2189153183"]},"w206805246":{"id":"w206805246","tags":{"area":"yes","building":"yes"},"nodes":["n2168544782","n2168544780","n2168544781","n2168544783","n2168544787","n2168544784","n2168544782"]},"w203970138":{"id":"w203970138","tags":{"building":"yes"},"nodes":["n2139824729","n2139824720","n2139824702","n2139824707","n2139824729"]},"w203970133":{"id":"w203970133","tags":{"building":"yes"},"nodes":["n2139824748","n2139824737","n2139824717","n2139824728","n2139824748"]},"w203970907":{"id":"w203970907","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2139832700","n2139832701","n2139832702"]},"w203974056":{"id":"w203974056","tags":{"highway":"path","name":"Riverwalk Trail"},"nodes":["n2139870377","n2139870378"]},"w203970897":{"id":"w203970897","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2130304156","n2166205688","n2139832635","n2139832636","n2139832637","n2139832639","n2139832641","n2166205688"]},"w203974057":{"id":"w203974057","tags":{"highway":"path","name":"Riverwalk Trail"},"nodes":["n2139870375","n2139870376"]},"w203049594":{"id":"w203049594","tags":{"highway":"service"},"nodes":["n2130304156","n2139870378","n2139832706","n2139832704","n2130304157"]},"w203970122":{"id":"w203970122","tags":{"building":"yes"},"nodes":["n2139824757","n2139824740","n2139824747","n2139824762","n2139824757"]},"w208643136":{"id":"w208643136","tags":{"area":"yes","building":"yes"},"nodes":["n2189153219","n2189153220","n2189153221","n2189153222","n2189153223","n2189153224","n2189153225","n2189153226","n2189153219"]},"w203970128":{"id":"w203970128","tags":{"building":"yes"},"nodes":["n2139824732","n2139824752","n2139824744","n2139824724","n2139824732"]},"w203970097":{"id":"w203970097","tags":{"building":"yes"},"nodes":["n2139824737","n2139824733","n2139824710","n2139824716","n2139824737"]},"w203970137":{"id":"w203970137","tags":{"building":"yes"},"nodes":["n2139824765","n2139824774","n2139824758","n2139824746","n2139824765"]},"w134150840":{"id":"w134150840","tags":{"highway":"residential","name":"Moore St"},"nodes":["n1475284019","n185988243","n185988244","n185988245"]},"w17967628":{"id":"w17967628","tags":{"highway":"residential","name":"Moore St"},"nodes":["n185978388","n2139832709","n185988237","n185988239"]},"w203988292":{"id":"w203988292","tags":{"bridge":"yes","highway":"footway"},"nodes":["n2140006407","n2140006405"]},"w203970118":{"id":"w203970118","tags":{"building":"yes"},"nodes":["n2139824775","n2139824785","n2139824780","n2139824768","n2139824775"]},"w203970121":{"id":"w203970121","tags":{"building":"yes"},"nodes":["n2139824768","n2139824781","n2139824776","n2139824765","n2139824768"]},"w17967752":{"id":"w17967752","tags":{"highway":"residential","name":"Railroad Drive"},"nodes":["n185964980","n2139832699","n2139832700","n2130304158","n185988969","n185988971","n185988972","n1475284011"]},"w203970136":{"id":"w203970136","tags":{"building":"yes"},"nodes":["n2139824798","n2139824793","n2139824777","n2139824784","n2139824798"]},"w203970142":{"id":"w203970142","tags":{"building":"yes"},"nodes":["n2139824808","n2139824809","n2139824807","n2139824806","n2139824801","n2139824800","n2139824804","n2139824805","n2139824808"]},"w208643137":{"id":"w208643137","tags":{"amenity":"parking","area":"yes"},"nodes":["n2189153227","n2189153248","n2189153228","n2189153234","n2189153235","n2189153229","n2189153249","n2189153230","n2189153227"]},"w208643129":{"id":"w208643129","tags":{"area":"yes","building":"yes"},"nodes":["n2189153179","n2189153180","n2189153181","n2189153182","n2189153179"]},"w203970909":{"id":"w203970909","tags":{"amenity":"parking","area":"yes"},"nodes":["n2139832703","n2139832704","n2139832706","n2139832708","n2139832703"]},"w203970905":{"id":"w203970905","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2139832688","n2139832691"]},"w203988298":{"id":"w203988298","tags":{"highway":"service"},"nodes":["n2140006431","n2140006433","n2140006435","n2140006436","n2140006437","n2140006438","n2140006439","n2140006440"]},"w203970106":{"id":"w203970106","tags":{"building":"yes"},"nodes":["n2139824798","n2139824791","n2139824799","n2139824802","n2139824798"]},"w203970129":{"id":"w203970129","tags":{"building":"yes"},"nodes":["n2139824787","n2139824782","n2139824766","n2139824769","n2139824787"]},"w208643131":{"id":"w208643131","tags":{"area":"yes","building":"yes"},"nodes":["n2189153191","n2189153192","n2189153193","n2189153194","n2189153191"]},"w206805249":{"id":"w206805249","tags":{"area":"yes","building":"yes"},"nodes":["n2168544800","n2168544801","n2168544802","n2168544805","n2168544807","n2168544809","n2168544811","n2168544813","n2168544815","n2168544817","n2168544819","n2168544821","n2168544823","n2168544825","n2168544800"]},"w134150800":{"id":"w134150800","tags":{"bridge":"yes","highway":"primary","name":"W Michigan Ave","old_ref":"US 131","ref":"US 131 Business;M 60"},"nodes":["n185964972","n185964976"]},"w17966984":{"id":"w17966984","tags":{"highway":"residential","name":"Portage Avenue"},"nodes":["n185978375","n185963456","n2189153218","n185966937","n185978967","n185967422","n185982193","n185968100","n185982195","n185960195","n185980735","n185978787","n185966948","n185982196","n185982197","n185982198","n185982200","n2139795768","n185972155"]},"w203988294":{"id":"w203988294","tags":{"amenity":"shelter","area":"yes","building":"yes","shelter_type":"picnic_shelter"},"nodes":["n2140006409","n2140006411","n2140006413","n2140006415","n2140006409"]},"w203970912":{"id":"w203970912","tags":{"amenity":"parking","area":"yes"},"nodes":["n2139832711","n2139832712","n2139832713","n2139832714","n2139832711"]},"w203970119":{"id":"w203970119","tags":{"building":"yes"},"nodes":["n2139824713","n2139824705","n2139824683","n2139824689","n2139824713"]},"w203970114":{"id":"w203970114","tags":{"building":"yes"},"nodes":["n2139824735","n2139824750","n2139824745","n2139824732","n2139824735"]},"w208643142":{"id":"w208643142","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2189153254","n2189153255","n2189153256","n2189153257"]},"w206805253":{"id":"w206805253","tags":{"area":"yes","building":"yes"},"nodes":["n2168544848","n2168544849","n2168544850","n2168544851","n2168544852","n2168544853","n2168544854","n2168544855","n2168544848"]},"w143497377":{"id":"w143497377","tags":{"highway":"primary","name":"North Main Street","old_ref":"US 131","ref":"US 131 Business"},"nodes":["n185962625","n185978420","n185978419","n185978417","n185978415","n185978414","n185975735","n1475293254","n185978410","n185978406","n185970515","n185978402","n185978399","n185965399","n2189015992","n185961396","n185967917","n185978394","n185971631","n185960796","n185978392","n185974583","n185978390","n185971578","n185965289","n2189153215","n185978388","n185978383","n185978381","n185978379","n185978377","n185978375","n185964982"]},"w134150811":{"id":"w134150811","tags":{"highway":"primary","name":"West Michigan Avenue","old_ref":"US 131","ref":"US 131 Business;M 60"},"nodes":["n185964976","n2130304157","n1475284023","n2139832715","n185964980","n185964982"]},"w208643135":{"id":"w208643135","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2189153215","n2189153216","n2189153217","n2189153218"]},"w17967183":{"id":"w17967183","tags":{"highway":"residential","name":"West Street"},"nodes":["n1475284011","n185984011","n185984013","n185984015","n2189153246","n2189153250","n185965291","n185984017","n185971580","n185984020","n185974585","n185982163","n185975064","n185971632","n185984022","n185984024","n185967918"]},"w134150778":{"id":"w134150778","tags":{"bridge":"yes","highway":"residential","name":"Moore St"},"nodes":["n185988245","n1475283992","n185975911"]},"w206805248":{"id":"w206805248","tags":{"area":"yes","building":"yes"},"nodes":["n2168544790","n2168544791","n2168544792","n2168544793","n2168544795","n2168544797","n2168544798","n2168544799","n2168544802","n2168544801","n2168544790"]},"w203974058":{"id":"w203974058","tags":{"bridge":"yes","highway":"path","name":"Riverwalk Trail"},"nodes":["n2139870374","n2139870375"]},"w203970902":{"id":"w203970902","tags":{"highway":"service"},"nodes":["n2139832678","n2139832691","n2139832680"]},"w203988296":{"id":"w203988296","tags":{"highway":"path"},"nodes":["n2139858967","n2140006421","n2139858935"]},"w206805251":{"id":"w206805251","tags":{"area":"yes","building":"yes"},"nodes":["n2168544830","n2168544831","n2168544832","n2168544833","n2168544834","n2168544835","n2168544836","n2168544837","n2168544830"]},"w203970906":{"id":"w203970906","tags":{"amenity":"parking","area":"yes"},"nodes":["n2139832693","n2139832694","n2139832696","n2139832697","n2139832698","n2139832693"]},"w203049598":{"id":"w203049598","tags":{"area":"yes","leisure":"pitch","sport":"tennis"},"nodes":["n2130304162","n2130304163","n2130304164","n2130304165","n2130304162"]},"w203970911":{"id":"w203970911","tags":{"highway":"service"},"nodes":["n2139832709","n2139832714","n2139832713","n2139832710","n185988971"]},"w203970105":{"id":"w203970105","tags":{"building":"yes"},"nodes":["n2139824779","n2139824792","n2139824786","n2139824775","n2139824779"]},"w203988290":{"id":"w203988290","tags":{"highway":"footway"},"nodes":["n2140006403","n2140006407"]},"w203970900":{"id":"w203970900","tags":{"amenity":"parking","area":"yes"},"nodes":["n2139832653","n2139832663","n2139832665","n2139832667","n2139832669","n2139832671","n2139832673","n2139832675","n2139832677","n2139832653"]},"w209717048":{"id":"w209717048","tags":{"area":"yes","building":"yes"},"nodes":["n2199109755","n2199109756","n2199109757","n2199109758","n2199109759","n2199109760","n2199109755"]},"w208643141":{"id":"w208643141","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2189153247","n2189153248","n2189153249","n2189153250"]},"w203970903":{"id":"w203970903","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2139832682","n2139832688","n2139832684","n2139832678","n2139832686"]},"n354002527":{"id":"n354002527","loc":[-85.6236039,41.9458813],"tags":{"amenity":"school","name":"Barrows School"}},"n185963396":{"id":"n185963396","loc":[-85.627401,41.943496]},"n185963397":{"id":"n185963397","loc":[-85.627403,41.943625]},"n185965101":{"id":"n185965101","loc":[-85.626409,41.943215]},"n185971474":{"id":"n185971474","loc":[-85.624884,41.943508]},"n185971475":{"id":"n185971475","loc":[-85.625191,41.943509]},"n185971482":{"id":"n185971482","loc":[-85.624882,41.94382]},"n185983135":{"id":"n185983135","loc":[-85.624893,41.945616]},"n185983137":{"id":"n185983137","loc":[-85.624912,41.946524]},"n185988027":{"id":"n185988027","loc":[-85.622721,41.946535]},"n185963398":{"id":"n185963398","loc":[-85.6273993,41.9446899]},"n185983238":{"id":"n185983238","loc":[-85.6227157,41.9456321]},"n185980374":{"id":"n185980374","loc":[-85.6248856,41.9447242]},"n185980373":{"id":"n185980373","loc":[-85.6226744,41.9447371]},"n2196831342":{"id":"n2196831342","loc":[-85.6250924,41.945063]},"n2196831343":{"id":"n2196831343","loc":[-85.6252335,41.9450636]},"n2196831344":{"id":"n2196831344","loc":[-85.6252286,41.9448707]},"n2196831345":{"id":"n2196831345","loc":[-85.6250661,41.9448707]},"n2196831346":{"id":"n2196831346","loc":[-85.6250243,41.9449012]},"n2196831347":{"id":"n2196831347","loc":[-85.6250251,41.9449244]},"n2196831348":{"id":"n2196831348","loc":[-85.6250867,41.9449257]},"n2196831349":{"id":"n2196831349","loc":[-85.625349,41.9445058]},"n2196831350":{"id":"n2196831350","loc":[-85.6253471,41.9443882]},"n2196831351":{"id":"n2196831351","loc":[-85.6251516,41.94439]},"n2196831352":{"id":"n2196831352","loc":[-85.6251522,41.9444308]},"n2196831353":{"id":"n2196831353","loc":[-85.6251344,41.9444309]},"n2196831354":{"id":"n2196831354","loc":[-85.6251356,41.9445077]},"n2196831355":{"id":"n2196831355","loc":[-85.6232357,41.9463406]},"n2196831356":{"id":"n2196831356","loc":[-85.6232409,41.9460668]},"n2196831357":{"id":"n2196831357","loc":[-85.6232072,41.9460665]},"n2196831358":{"id":"n2196831358","loc":[-85.6232117,41.9458272]},"n2196831359":{"id":"n2196831359","loc":[-85.6229808,41.9458248]},"n2196831360":{"id":"n2196831360","loc":[-85.6229763,41.9460627]},"n2196831361":{"id":"n2196831361","loc":[-85.623006,41.946063]},"n2196831362":{"id":"n2196831362","loc":[-85.6230023,41.9462557]},"n2196831363":{"id":"n2196831363","loc":[-85.6230755,41.9462565]},"n2196831364":{"id":"n2196831364","loc":[-85.6230739,41.9463389]},"n185947349":{"id":"n185947349","loc":[-85.618327,41.945607]},"n185947359":{"id":"n185947359","loc":[-85.615453,41.945597]},"n185947378":{"id":"n185947378","loc":[-85.617231,41.945603]},"n185947474":{"id":"n185947474","loc":[-85.616136,41.945602]},"n185948972":{"id":"n185948972","loc":[-85.615273,41.945637]},"n185955019":{"id":"n185955019","loc":[-85.620172,41.945627]},"n185960682":{"id":"n185960682","loc":[-85.622759,41.951845]},"n185961369":{"id":"n185961369","loc":[-85.622758,41.947444]},"n185961371":{"id":"n185961371","loc":[-85.624908,41.947416]},"n185963392":{"id":"n185963392","loc":[-85.6270462,41.9409953]},"n185963393":{"id":"n185963393","loc":[-85.627295,41.941304]},"n185963394":{"id":"n185963394","loc":[-85.627352,41.94148]},"n185963395":{"id":"n185963395","loc":[-85.62737,41.942261]},"n185965099":{"id":"n185965099","loc":[-85.6264,41.942263]},"n185965108":{"id":"n185965108","loc":[-85.622769,41.949224]},"n185965110":{"id":"n185965110","loc":[-85.624937,41.949237]},"n185966295":{"id":"n185966295","loc":[-85.6299942,41.9446689]},"n185966342":{"id":"n185966342","loc":[-85.624873,41.942022]},"n185970222":{"id":"n185970222","loc":[-85.622761,41.948357]},"n185970224":{"id":"n185970224","loc":[-85.624924,41.9483338]},"n185971477":{"id":"n185971477","loc":[-85.620051,41.94383]},"n185971478":{"id":"n185971478","loc":[-85.621219,41.943801]},"n185971481":{"id":"n185971481","loc":[-85.621812,41.943807]},"n185973866":{"id":"n185973866","loc":[-85.627629,41.946498]},"n185974699":{"id":"n185974699","loc":[-85.6227688,41.950119]},"n185978800":{"id":"n185978800","loc":[-85.623953,41.954684]},"n185980372":{"id":"n185980372","loc":[-85.621459,41.944756]},"n185980378":{"id":"n185980378","loc":[-85.6286375,41.9446764]},"n185980380":{"id":"n185980380","loc":[-85.630139,41.944661]},"n185980382":{"id":"n185980382","loc":[-85.630298,41.944635]},"n185980384":{"id":"n185980384","loc":[-85.630759,41.94454]},"n185980386":{"id":"n185980386","loc":[-85.6312369,41.9444548]},"n185983133":{"id":"n185983133","loc":[-85.6248672,41.9415903]},"n185983139":{"id":"n185983139","loc":[-85.624951,41.950239]},"n185983140":{"id":"n185983140","loc":[-85.624934,41.950681]},"n185983141":{"id":"n185983141","loc":[-85.624813,41.950983]},"n185983143":{"id":"n185983143","loc":[-85.6246225,41.951591]},"n185983144":{"id":"n185983144","loc":[-85.623908,41.9539165]},"n185983145":{"id":"n185983145","loc":[-85.6238903,41.9540956]},"n185983146":{"id":"n185983146","loc":[-85.623898,41.95431]},"n185983236":{"id":"n185983236","loc":[-85.628481,41.945611]},"n185985914":{"id":"n185985914","loc":[-85.620072,41.946538]},"n185986812":{"id":"n185986812","loc":[-85.6227785,41.9510005]},"n185988028":{"id":"n185988028","loc":[-85.6281401,41.9469632]},"n185988030":{"id":"n185988030","loc":[-85.6282451,41.9470314]},"n185988032":{"id":"n185988032","loc":[-85.6283312,41.9470656]},"w17964989":{"id":"w17964989","tags":{"highway":"residential","name":"Middle St"},"nodes":["n185963392","n185963393","n185963394","n185963395","n185963396","n185963397","n185963398"]},"w17965158":{"id":"w17965158","tags":{"access":"private","highway":"service","name":"Battle St"},"nodes":["n185965099","n185965101"]},"w41074896":{"id":"w41074896","tags":{"highway":"secondary","name":"East Michigan Avenue","name_1":"State Highway 60","ref":"M 60"},"nodes":["n185980372","n185980373","n185980374","n185963398","n185980378","n185966295","n185980380","n185980382","n185980384","n185980386"]},"w17965846":{"id":"w17965846","tags":{"highway":"residential","name":"2nd Ave"},"nodes":["n185971477","n185971478","n185971481","n185971482"]},"w209470306":{"id":"w209470306","tags":{"area":"yes","building":"yes"},"nodes":["n2196831349","n2196831350","n2196831351","n2196831352","n2196831353","n2196831354","n2196831349"]},"w17965845":{"id":"w17965845","tags":{"highway":"residential","name":"2nd Ave"},"nodes":["n185971474","n185971475","n185963396"]},"w209470307":{"id":"w209470307","tags":{"area":"yes","building":"yes"},"nodes":["n2196831355","n2196831356","n2196831357","n2196831358","n2196831359","n2196831360","n2196831361","n2196831362","n2196831363","n2196831364","n2196831355"]},"w17968192":{"id":"w17968192","tags":{"highway":"residential","name":"Washington St"},"nodes":["n185980373","n185983238","n185988027","n185961369","n185970222","n185965108","n185974699","n185986812","n185960682"]},"w17967603":{"id":"w17967603","tags":{"highway":"residential","name":"5th Ave"},"nodes":["n185985914","n185988027","n185983137","n185973866","n185988028","n185988030","n185988032"]},"w209470305":{"id":"w209470305","tags":{"area":"yes","building":"yes"},"nodes":["n2196831342","n2196831343","n2196831344","n2196831345","n2196831346","n2196831347","n2196831348","n2196831342"]},"w17967092":{"id":"w17967092","tags":{"highway":"residential","name":"Wood St"},"nodes":["n185983133","n185966342","n185971474","n185971482","n185980374","n185983135","n185983137","n185961371","n185970224","n185965110","n185983139","n185983140","n185983141","n185983143","n185983144","n185983145","n185983146","n185978800"]},"w17967107":{"id":"w17967107","tags":{"highway":"residential","name":"4th Ave"},"nodes":["n185983236","n185983135","n185983238","n185955019","n185947349","n185947378","n185947474","n185947359","n185948972"]},"n354030330":{"id":"n354030330","loc":[-85.6297222,41.9444444],"tags":{"leisure":"park","name":"Scouter Park"}},"n185966296":{"id":"n185966296","loc":[-85.629998,41.944078]},"n185966298":{"id":"n185966298","loc":[-85.629972,41.943927]},"n185966300":{"id":"n185966300","loc":[-85.629948,41.943783]},"n185980391":{"id":"n185980391","loc":[-85.6322992,41.9442766]},"n185980393":{"id":"n185980393","loc":[-85.6324925,41.9442136]},"n185980389":{"id":"n185980389","loc":[-85.6320272,41.9443281]},"n185980388":{"id":"n185980388","loc":[-85.6315778,41.9443959]},"n354031320":{"id":"n354031320","loc":[-85.6280556,41.9447222],"tags":{"amenity":"place_of_worship","name":"Riverside Church","religion":"christian"}},"n185987309":{"id":"n185987309","loc":[-85.6286497,41.9453531]},"n185987311":{"id":"n185987311","loc":[-85.6285942,41.9454805]},"n185988034":{"id":"n185988034","loc":[-85.6285815,41.9471692]},"n185988896":{"id":"n185988896","loc":[-85.6318433,41.9437929]},"n185977764":{"id":"n185977764","loc":[-85.6322988,41.943472]},"n1819848852":{"id":"n1819848852","loc":[-85.6315188,41.9448808]},"n1819848912":{"id":"n1819848912","loc":[-85.6284289,41.9472189]},"n1819848925":{"id":"n1819848925","loc":[-85.6314501,41.9451617]},"n1819848949":{"id":"n1819848949","loc":[-85.6309394,41.9455192]},"n1819848951":{"id":"n1819848951","loc":[-85.6290297,41.9457187]},"n1819848963":{"id":"n1819848963","loc":[-85.630521,41.9455591]},"n1819848981":{"id":"n1819848981","loc":[-85.6292936,41.9455846]},"n1819848989":{"id":"n1819848989","loc":[-85.6298451,41.9455431]},"n1819848998":{"id":"n1819848998","loc":[-85.6314973,41.9446254]},"n1819849018":{"id":"n1819849018","loc":[-85.6302807,41.9455527]},"n1819849043":{"id":"n1819849043","loc":[-85.6285533,41.9469731]},"n1819849087":{"id":"n1819849087","loc":[-85.6314501,41.9453532]},"n1819849090":{"id":"n1819849090","loc":[-85.628843,41.9461033]},"n1819849109":{"id":"n1819849109","loc":[-85.6311926,41.9454729]},"n1819849116":{"id":"n1819849116","loc":[-85.6288967,41.9459437]},"n1819849177":{"id":"n1819849177","loc":[-85.6287894,41.9464544]},"n1819858529":{"id":"n1819858529","loc":[-85.6325485,41.9445625]},"n2189112797":{"id":"n2189112797","loc":[-85.6275271,41.944555]},"n2189112798":{"id":"n2189112798","loc":[-85.6275196,41.9437258]},"n2189112799":{"id":"n2189112799","loc":[-85.6278937,41.943723]},"n2189112800":{"id":"n2189112800","loc":[-85.6278969,41.9439191]},"n2189112801":{"id":"n2189112801","loc":[-85.6279907,41.9439345]},"n2189112802":{"id":"n2189112802","loc":[-85.6280817,41.9439663]},"n2189112803":{"id":"n2189112803","loc":[-85.6281768,41.9440145]},"n2189112804":{"id":"n2189112804","loc":[-85.6281933,41.9440483]},"n2189112805":{"id":"n2189112805","loc":[-85.6281671,41.9440535]},"n2189112806":{"id":"n2189112806","loc":[-85.6281933,41.9440935]},"n2189112807":{"id":"n2189112807","loc":[-85.6282126,41.9441437]},"n2189112808":{"id":"n2189112808","loc":[-85.628214,41.9441991]},"n2189112809":{"id":"n2189112809","loc":[-85.6283298,41.944196]},"n2189112810":{"id":"n2189112810","loc":[-85.6283285,41.9442616]},"n2189112811":{"id":"n2189112811","loc":[-85.6281727,41.9442616]},"n2189112812":{"id":"n2189112812","loc":[-85.6281713,41.9442934]},"n2189112813":{"id":"n2189112813","loc":[-85.6280386,41.9442963]},"n2189112814":{"id":"n2189112814","loc":[-85.6280405,41.9443292]},"n2189112815":{"id":"n2189112815","loc":[-85.627829,41.9443349]},"n2189112816":{"id":"n2189112816","loc":[-85.6278347,41.9445495]},"n2189153271":{"id":"n2189153271","loc":[-85.6321053,41.9460342]},"n2189153272":{"id":"n2189153272","loc":[-85.632278,41.9457841]},"n2189153273":{"id":"n2189153273","loc":[-85.632823,41.9459936]},"n2189153274":{"id":"n2189153274","loc":[-85.6326845,41.9461963]},"n2189153275":{"id":"n2189153275","loc":[-85.6325664,41.9461507]},"n2189153276":{"id":"n2189153276","loc":[-85.6325323,41.946198]},"n2189153278":{"id":"n2189153278","loc":[-85.6321916,41.9459733]},"n2189153279":{"id":"n2189153279","loc":[-85.6322598,41.9458703]},"n2189153280":{"id":"n2189153280","loc":[-85.6327208,41.9460358]},"n2189153281":{"id":"n2189153281","loc":[-85.6326413,41.9461422]},"n185959079":{"id":"n185959079","loc":[-85.6293702,41.9474668]},"n185966301":{"id":"n185966301","loc":[-85.629692,41.943136]},"n185966304":{"id":"n185966304","loc":[-85.629565,41.942916]},"n185966308":{"id":"n185966308","loc":[-85.629501,41.942751]},"n185966315":{"id":"n185966315","loc":[-85.629472,41.942578]},"n185966319":{"id":"n185966319","loc":[-85.629444,41.942414]},"n185966321":{"id":"n185966321","loc":[-85.629391,41.94205]},"n185966323":{"id":"n185966323","loc":[-85.629369,41.941858]},"n185966327":{"id":"n185966327","loc":[-85.629297,41.941604]},"n185966331":{"id":"n185966331","loc":[-85.629233,41.941549]},"n185966336":{"id":"n185966336","loc":[-85.628504,41.941364]},"n185966338":{"id":"n185966338","loc":[-85.628275,41.941303]},"n185966340":{"id":"n185966340","loc":[-85.6269038,41.9410983]},"n185973867":{"id":"n185973867","loc":[-85.626843,41.947333]},"n185977762":{"id":"n185977762","loc":[-85.6318441,41.9429453]},"n1819848853":{"id":"n1819848853","loc":[-85.625854,41.9492218]},"n1819848861":{"id":"n1819848861","loc":[-85.6251459,41.9552376]},"n1819848874":{"id":"n1819848874","loc":[-85.6267445,41.9482961]},"n1819848882":{"id":"n1819848882","loc":[-85.6257209,41.9552396]},"n1819848883":{"id":"n1819848883","loc":[-85.624706,41.9523173]},"n1819848907":{"id":"n1819848907","loc":[-85.62609,41.9561471]},"n1819848908":{"id":"n1819848908","loc":[-85.6244013,41.9549284]},"n1819848911":{"id":"n1819848911","loc":[-85.6265578,41.9553672]},"n1819848923":{"id":"n1819848923","loc":[-85.6246802,41.9550959]},"n1819848936":{"id":"n1819848936","loc":[-85.6241588,41.9539291]},"n1819848940":{"id":"n1819848940","loc":[-85.62506,41.9511129]},"n1819848944":{"id":"n1819848944","loc":[-85.624942,41.9515912]},"n1819848950":{"id":"n1819848950","loc":[-85.6273989,41.9475461]},"n1819848957":{"id":"n1819848957","loc":[-85.627695,41.947404]},"n1819849009":{"id":"n1819849009","loc":[-85.6259248,41.94896]},"n1819849037":{"id":"n1819849037","loc":[-85.6257252,41.9502112]},"n1819849061":{"id":"n1819849061","loc":[-85.6270084,41.9479626]},"n1819849073":{"id":"n1819849073","loc":[-85.6243734,41.9534583]},"n1819849091":{"id":"n1819849091","loc":[-85.6241373,41.9543918]},"n1819849130":{"id":"n1819849130","loc":[-85.6282572,41.9473067]},"n1819849143":{"id":"n1819849143","loc":[-85.625281,41.9506596]},"n1819849153":{"id":"n1819849153","loc":[-85.6258647,41.9498043]},"n1819849168":{"id":"n1819849168","loc":[-85.6265084,41.9559317]},"n1819849173":{"id":"n1819849173","loc":[-85.6263325,41.9552156]},"n1819849175":{"id":"n1819849175","loc":[-85.6266372,41.9556764]},"n1819849178":{"id":"n1819849178","loc":[-85.6242232,41.9545993]},"n1819849181":{"id":"n1819849181","loc":[-85.6262187,41.9486712]},"n1819849188":{"id":"n1819849188","loc":[-85.6245558,41.9530434]},"n1819849190":{"id":"n1819849190","loc":[-85.6255982,41.9563017]},"n2168544738":{"id":"n2168544738","loc":[-85.6245707,41.9529711]},"w208643145":{"id":"w208643145","tags":{"amenity":"parking","area":"yes"},"nodes":["n2189153271","n2189153272","n2189153273","n2189153274","n2189153275","n2189153276","n2189153271"]},"w17967561":{"id":"w17967561","tags":{"highway":"residential","name":"Garden St"},"nodes":["n185980378","n185987309","n185987311","n185983236","n185973866"]},"w134150802":{"id":"w134150802","tags":{"bridge":"yes","highway":"secondary","name":"East Michigan Avenue","name_1":"State Highway 60","ref":"M 60"},"nodes":["n185980386","n185980388"]},"w208639462":{"id":"w208639462","tags":{"area":"yes","building":"yes"},"nodes":["n2189112797","n2189112798","n2189112799","n2189112800","n2189112801","n2189112802","n2189112803","n2189112804","n2189112805","n2189112806","n2189112807","n2189112808","n2189112809","n2189112810","n2189112811","n2189112812","n2189112813","n2189112814","n2189112815","n2189112816","n2189112797"]},"w134150830":{"id":"w134150830","tags":{"bridge":"yes","highway":"secondary","name":"South Main Street","old_ref":"US 131","ref":"M 86"},"nodes":["n185977762","n185977764"]},"w134150801":{"id":"w134150801","tags":{"highway":"secondary","name":"South Main Street","old_ref":"US 131","ref":"M 86"},"nodes":["n185977764","n185964982"]},"w208643146":{"id":"w208643146","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2189153277","n2189153281","n2189153278","n2189153279","n2189153280","n2189153281"]},"w17966061":{"id":"w17966061","tags":{"highway":"residential","name":"John Glenn Ct"},"nodes":["n185973866","n185973867"]},"w134150772":{"id":"w134150772","tags":{"highway":"residential","name":"5th Ave"},"nodes":["n185988034","n185959079","n185988036","n185978967"]},"w134150836":{"id":"w134150836","tags":{"highway":"secondary","name":"East Michigan Avenue","name_1":"State Highway 60","ref":"M 60"},"nodes":["n185980388","n1819858524","n185980389","n185980391","n185980393","n185964982"]},"w17967734":{"id":"w17967734","tags":{"highway":"residential","name":"Water Street"},"nodes":["n185988896","n185980391","n1819858529"]},"w17965305":{"id":"w17965305","tags":{"highway":"residential","name":"River Dr"},"nodes":["n185966295","n185966296","n185966298","n185966300","n185966301","n185966304","n185966308","n185966315","n185966319","n185966321","n185966323","n185966327","n185966331","n185966336","n185966338","n185963392","n185966340","n185966342"]},"w134150826":{"id":"w134150826","tags":{"bridge":"yes","highway":"residential","name":"5th Ave"},"nodes":["n185988032","n185988034"]},"w170848330":{"id":"w170848330","tags":{"name":"Portage River","waterway":"river"},"nodes":["n1819849190","n1819848907","n1819849168","n1819849175","n1819848911","n1819849173","n1819848882","n1819848861","n1819848923","n1819848908","n1819849178","n1819849091","n1819848936","n1819849073","n1819849188","n2168544738","n1819848883","n1819848944","n1819848940","n1819849143","n1819849037","n1819849153","n1819848853","n1819849009","n1819849181","n1819848874","n1819849061","n1819848950","n1819848957","n1819849130","n1819848912","n1819849043","n1819849177","n1819849090","n1819849116","n1819848951","n1819848981","n1819848989","n1819849018","n1819848963","n1819848949","n1819849109","n1819849087","n1819848925","n1819848852","n1819848998","n1819849057"]},"r270264":{"id":"r270264","tags":{"network":"US:MI","ref":"86","route":"road","state_id":"MI","type":"route","url":"http://en.wikipedia.org/wiki/M-86_%28Michigan_highway%29"},"members":[{"id":"w17737723","type":"way","role":""},{"id":"w17735949","type":"way","role":""},{"id":"w17740404","type":"way","role":""},{"id":"w17966273","type":"way","role":""},{"id":"w17964745","type":"way","role":""},{"id":"w151538068","type":"way","role":""},{"id":"w151538067","type":"way","role":""},{"id":"w17964960","type":"way","role":""},{"id":"w17966099","type":"way","role":""},{"id":"w17968009","type":"way","role":""},{"id":"w41259499","type":"way","role":""},{"id":"w151540401","type":"way","role":""},{"id":"w151540418","type":"way","role":""},{"id":"w17967997","type":"way","role":""},{"id":"w17966029","type":"way","role":""},{"id":"w17964801","type":"way","role":""},{"id":"w41259496","type":"way","role":""},{"id":"w151540399","type":"way","role":""},{"id":"w17968004","type":"way","role":""},{"id":"w17966462","type":"way","role":""},{"id":"w134150830","type":"way","role":""},{"id":"w134150801","type":"way","role":""},{"id":"w17732295","type":"way","role":""}]},"n185980093":{"id":"n185980093","loc":[-85.6271414,41.9407274]},"n185964330":{"id":"n185964330","loc":[-85.6235688,41.9399111]},"n185964328":{"id":"n185964328","loc":[-85.6235609,41.9391301]},"n185958034":{"id":"n185958034","loc":[-85.627102,41.939125]},"n185964331":{"id":"n185964331","loc":[-85.623571,41.940124]},"n185964329":{"id":"n185964329","loc":[-85.623562,41.9392411]},"n185972756":{"id":"n185972756","loc":[-85.623802,41.939102]},"n185972757":{"id":"n185972757","loc":[-85.623584,41.93913]},"n185975325":{"id":"n185975325","loc":[-85.624835,41.939318]},"n185975326":{"id":"n185975326","loc":[-85.624811,41.939435]},"n185975327":{"id":"n185975327","loc":[-85.624635,41.939703]},"n185975328":{"id":"n185975328","loc":[-85.624366,41.940055]},"n185975330":{"id":"n185975330","loc":[-85.624287,41.940113]},"n185975332":{"id":"n185975332","loc":[-85.624215,41.940134]},"n185980088":{"id":"n185980088","loc":[-85.627127,41.940086]},"n185988943":{"id":"n185988943","loc":[-85.622643,41.940128]},"n185988961":{"id":"n185988961","loc":[-85.627263,41.940082]},"n185990192":{"id":"n185990192","loc":[-85.622933,41.939224]},"n185990194":{"id":"n185990194","loc":[-85.621976,41.939203]},"n185991378":{"id":"n185991378","loc":[-85.622643,41.940635]},"n1475283999":{"id":"n1475283999","loc":[-85.6271165,41.9408429]},"n185980090":{"id":"n185980090","loc":[-85.6271315,41.9402001]},"n185958036":{"id":"n185958036","loc":[-85.6248366,41.9391615]},"n1819800188":{"id":"n1819800188","loc":[-85.6246947,41.9401644]},"n1819800199":{"id":"n1819800199","loc":[-85.6233686,41.9430896]},"n1819800204":{"id":"n1819800204","loc":[-85.6223236,41.9408587]},"n1819800213":{"id":"n1819800213","loc":[-85.6247526,41.9414138]},"n1819800216":{"id":"n1819800216","loc":[-85.6230961,41.9407151]},"n1819800218":{"id":"n1819800218","loc":[-85.621991,41.9429336]},"n1819800221":{"id":"n1819800221","loc":[-85.6246088,41.9424708]},"n1819800227":{"id":"n1819800227","loc":[-85.6241368,41.9403081]},"n1819800230":{"id":"n1819800230","loc":[-85.6226776,41.9431012]},"n1819800231":{"id":"n1819800231","loc":[-85.6243728,41.9401644]},"n1819800232":{"id":"n1819800232","loc":[-85.6249629,41.9408907]},"n1819800248":{"id":"n1819800248","loc":[-85.6238685,41.9405555]},"n1819800266":{"id":"n1819800266","loc":[-85.6246882,41.9418367]},"n1819800271":{"id":"n1819800271","loc":[-85.62492,41.9413695]},"n1819800294":{"id":"n1819800294","loc":[-85.6243556,41.9427465]},"n1819800304":{"id":"n1819800304","loc":[-85.6251453,41.94117]},"n1819800325":{"id":"n1819800325","loc":[-85.6248234,41.9405714]},"n1819800362":{"id":"n1819800362","loc":[-85.6239544,41.9429416]},"n1819800368":{"id":"n1819800368","loc":[-85.6243406,41.9402283]},"n1819800375":{"id":"n1819800375","loc":[-85.6226562,41.940755]},"n1819800377":{"id":"n1819800377","loc":[-85.6232033,41.9406512]},"n185945133":{"id":"n185945133","loc":[-85.623501,41.933232]},"n185945135":{"id":"n185945135","loc":[-85.624776,41.933205]},"n185945395":{"id":"n185945395","loc":[-85.624741,41.93019]},"n185952239":{"id":"n185952239","loc":[-85.615166,41.9382]},"n185954490":{"id":"n185954490","loc":[-85.624721,41.929278]},"n185957831":{"id":"n185957831","loc":[-85.625041,41.938662]},"n185958030":{"id":"n185958030","loc":[-85.629033,41.93913]},"n185958032":{"id":"n185958032","loc":[-85.628429,41.939143]},"n185958498":{"id":"n185958498","loc":[-85.621605,41.940143]},"n185961186":{"id":"n185961186","loc":[-85.624792,41.935214]},"n185963099":{"id":"n185963099","loc":[-85.6204461,41.9401485]},"n185963698":{"id":"n185963698","loc":[-85.6297342,41.9400783]},"n185964320":{"id":"n185964320","loc":[-85.623511,41.934216]},"n185964322":{"id":"n185964322","loc":[-85.6235312,41.9362084]},"n185964324":{"id":"n185964324","loc":[-85.6235488,41.9371726]},"n185964326":{"id":"n185964326","loc":[-85.6235512,41.9381718]},"n185967077":{"id":"n185967077","loc":[-85.617359,41.940161]},"n185967634":{"id":"n185967634","loc":[-85.6248039,41.9362012]},"n185970833":{"id":"n185970833","loc":[-85.6248019,41.9381684]},"n185972752":{"id":"n185972752","loc":[-85.624582,41.938848]},"n185972754":{"id":"n185972754","loc":[-85.6242,41.939008]},"n185973251":{"id":"n185973251","loc":[-85.602727,41.936012]},"n185974509":{"id":"n185974509","loc":[-85.62478,41.93217]},"n185975315":{"id":"n185975315","loc":[-85.624703,41.925597]},"n185975316":{"id":"n185975316","loc":[-85.624716,41.927359]},"n185975317":{"id":"n185975317","loc":[-85.62475,41.93119]},"n185975318":{"id":"n185975318","loc":[-85.624782,41.934218]},"n185975320":{"id":"n185975320","loc":[-85.6247949,41.9371708]},"n185977754":{"id":"n185977754","loc":[-85.6276,41.937412]},"n185980075":{"id":"n185980075","loc":[-85.627451,41.937549]},"n185980077":{"id":"n185980077","loc":[-85.627375,41.937618]},"n185980078":{"id":"n185980078","loc":[-85.627278,41.937728]},"n185980079":{"id":"n185980079","loc":[-85.627199,41.937842]},"n185980081":{"id":"n185980081","loc":[-85.627141,41.937981]},"n185980083":{"id":"n185980083","loc":[-85.627109,41.938153]},"n185980085":{"id":"n185980085","loc":[-85.627101,41.938699]},"n185981173":{"id":"n185981173","loc":[-85.61433,41.940167]},"n185987021":{"id":"n185987021","loc":[-85.628311,41.942261]},"n185988963":{"id":"n185988963","loc":[-85.628439,41.940086]},"n185990195":{"id":"n185990195","loc":[-85.621225,41.939143]},"n185990196":{"id":"n185990196","loc":[-85.620576,41.939033]},"n185990198":{"id":"n185990198","loc":[-85.619081,41.938804]},"n185990200":{"id":"n185990200","loc":[-85.617593,41.938552]},"n185990202":{"id":"n185990202","loc":[-85.617372,41.938535]},"n185990204":{"id":"n185990204","loc":[-85.616087,41.93832]},"n185990206":{"id":"n185990206","loc":[-85.615754,41.938289]},"n185990209":{"id":"n185990209","loc":[-85.615438,41.938251]},"n185990211":{"id":"n185990211","loc":[-85.613469,41.937867]},"n185990212":{"id":"n185990212","loc":[-85.610172,41.937298]},"n185990213":{"id":"n185990213","loc":[-85.605537,41.936497]},"n185990214":{"id":"n185990214","loc":[-85.604014,41.936234]},"n1819800180":{"id":"n1819800180","loc":[-85.588775,41.9455032]},"n1819800181":{"id":"n1819800181","loc":[-85.6074212,41.9408827]},"n1819800182":{"id":"n1819800182","loc":[-85.6131397,41.9427022]},"n1819800183":{"id":"n1819800183","loc":[-85.6171523,41.9416807]},"n1819800184":{"id":"n1819800184","loc":[-85.602465,41.9397415]},"n1819800185":{"id":"n1819800185","loc":[-85.6109296,41.9410583]},"n1819800186":{"id":"n1819800186","loc":[-85.6165729,41.9418004]},"n1819800189":{"id":"n1819800189","loc":[-85.5866293,41.9458224]},"n1819800191":{"id":"n1819800191","loc":[-85.5853311,41.9466603]},"n1819800201":{"id":"n1819800201","loc":[-85.6101142,41.9433406]},"n1819800202":{"id":"n1819800202","loc":[-85.600963,41.9428618]},"n1819800206":{"id":"n1819800206","loc":[-85.6154357,41.9427501]},"n1819800207":{"id":"n1819800207","loc":[-85.6040309,41.9414094]},"n1819800209":{"id":"n1819800209","loc":[-85.6113694,41.943189]},"n1819800211":{"id":"n1819800211","loc":[-85.618032,41.9416408]},"n1819800214":{"id":"n1819800214","loc":[-85.5959419,41.9402602]},"n1819800219":{"id":"n1819800219","loc":[-85.5972117,41.9420043]},"n1819800223":{"id":"n1819800223","loc":[-85.6117171,41.9430019]},"n1819800224":{"id":"n1819800224","loc":[-85.5977873,41.9395579]},"n1819800226":{"id":"n1819800226","loc":[-85.5917362,41.9432209]},"n1819800228":{"id":"n1819800228","loc":[-85.6055759,41.9419122]},"n1819800229":{"id":"n1819800229","loc":[-85.6203395,41.9425595]},"n1819800233":{"id":"n1819800233","loc":[-85.6107579,41.9433007]},"n1819800234":{"id":"n1819800234","loc":[-85.6039773,41.9412498]},"n1819800235":{"id":"n1819800235","loc":[-85.6000977,41.9412861]},"n1819800236":{"id":"n1819800236","loc":[-85.6026689,41.9407231]},"n1819800237":{"id":"n1819800237","loc":[-85.615161,41.9428662]},"n1819800238":{"id":"n1819800238","loc":[-85.5878953,41.9454314]},"n1819800239":{"id":"n1819800239","loc":[-85.6035267,41.941569]},"n1819800240":{"id":"n1819800240","loc":[-85.5929738,41.9450208]},"n1819800241":{"id":"n1819800241","loc":[-85.6186329,41.9416488]},"n1819800242":{"id":"n1819800242","loc":[-85.5881136,41.9483963]},"n1819800243":{"id":"n1819800243","loc":[-85.5909208,41.9466922]},"n1819800244":{"id":"n1819800244","loc":[-85.5997721,41.9394941]},"n1819800245":{"id":"n1819800245","loc":[-85.6202064,41.9425712]},"n1819800246":{"id":"n1819800246","loc":[-85.591071,41.9448808]},"n1819800247":{"id":"n1819800247","loc":[-85.5866078,41.9490622]},"n1819800250":{"id":"n1819800250","loc":[-85.602383,41.9420841]},"n1819800251":{"id":"n1819800251","loc":[-85.5957418,41.9426906]},"n1819800255":{"id":"n1819800255","loc":[-85.6157039,41.9416727]},"n1819800256":{"id":"n1819800256","loc":[-85.6080328,41.9410982]},"n1819800258":{"id":"n1819800258","loc":[-85.6192551,41.9414892]},"n1819800260":{"id":"n1819800260","loc":[-85.6104253,41.94117]},"n1819800261":{"id":"n1819800261","loc":[-85.6204503,41.9425709]},"n1819800263":{"id":"n1819800263","loc":[-85.5872194,41.9455431]},"n1819800264":{"id":"n1819800264","loc":[-85.616176,41.9418244]},"n1819800268":{"id":"n1819800268","loc":[-85.6120883,41.9426703]},"n1819800269":{"id":"n1819800269","loc":[-85.5894547,41.9474946]},"n1819800272":{"id":"n1819800272","loc":[-85.6209181,41.9425027]},"n1819800274":{"id":"n1819800274","loc":[-85.6122814,41.9412817]},"n1819800276":{"id":"n1819800276","loc":[-85.5895153,41.9452798]},"n1819800277":{"id":"n1819800277","loc":[-85.5884317,41.9455272]},"n1819800279":{"id":"n1819800279","loc":[-85.5884103,41.9480966]},"n1819800287":{"id":"n1819800287","loc":[-85.5904917,41.9453915]},"n1819800288":{"id":"n1819800288","loc":[-85.6212292,41.9412977]},"n1819800289":{"id":"n1819800289","loc":[-85.5954377,41.9406832]},"n1819800290":{"id":"n1819800290","loc":[-85.593721,41.9420957]},"n1819800291":{"id":"n1819800291","loc":[-85.6162832,41.9427102]},"n1819800292":{"id":"n1819800292","loc":[-85.605018,41.9401804]},"n1819800293":{"id":"n1819800293","loc":[-85.6086443,41.941146]},"n1819800296":{"id":"n1819800296","loc":[-85.6204675,41.9413775]},"n1819800297":{"id":"n1819800297","loc":[-85.612496,41.9424947]},"n1819800299":{"id":"n1819800299","loc":[-85.6065629,41.9423431]},"n1819800301":{"id":"n1819800301","loc":[-85.6036125,41.9398452]},"n1819800303":{"id":"n1819800303","loc":[-85.6114767,41.94117]},"n1819800306":{"id":"n1819800306","loc":[-85.592616,41.9428139]},"n1819800308":{"id":"n1819800308","loc":[-85.6023041,41.9419521]},"n1819800310":{"id":"n1819800310","loc":[-85.6218944,41.9411061]},"n1819800311":{"id":"n1819800311","loc":[-85.6097816,41.941162]},"n1819800312":{"id":"n1819800312","loc":[-85.5922549,41.9457869]},"n1819800313":{"id":"n1819800313","loc":[-85.5986027,41.9417206]},"n1819800314":{"id":"n1819800314","loc":[-85.5918687,41.946138]},"n1819800315":{"id":"n1819800315","loc":[-85.5872875,41.948883]},"n1819800316":{"id":"n1819800316","loc":[-85.594272,41.9436642]},"n1819800317":{"id":"n1819800317","loc":[-85.6176351,41.941577]},"n1819800318":{"id":"n1819800318","loc":[-85.6137834,41.9430853]},"n1819800319":{"id":"n1819800319","loc":[-85.6195383,41.942622],"tags":{"leisure":"slipway"}},"n1819800320":{"id":"n1819800320","loc":[-85.5971006,41.9398053]},"n1819800321":{"id":"n1819800321","loc":[-85.601714,41.9406752]},"n1819800322":{"id":"n1819800322","loc":[-85.5908028,41.9453117]},"n1819800323":{"id":"n1819800323","loc":[-85.6062732,41.9404597]},"n1819800324":{"id":"n1819800324","loc":[-85.62124,41.9425905]},"n1819800327":{"id":"n1819800327","loc":[-85.6008664,41.942766]},"n1819800328":{"id":"n1819800328","loc":[-85.6179355,41.9428538]},"n1819800330":{"id":"n1819800330","loc":[-85.6045566,41.9415131]},"n1819800331":{"id":"n1819800331","loc":[-85.5944935,41.9414653]},"n1819800333":{"id":"n1819800333","loc":[-85.6088911,41.943181]},"n1819800334":{"id":"n1819800334","loc":[-85.5946367,41.943369]},"n1819800336":{"id":"n1819800336","loc":[-85.6150494,41.9429656]},"n1819800343":{"id":"n1819800343","loc":[-85.6096099,41.9433326]},"n1819800345":{"id":"n1819800345","loc":[-85.5915216,41.9435401]},"n1819800347":{"id":"n1819800347","loc":[-85.607786,41.9428698]},"n1819800349":{"id":"n1819800349","loc":[-85.6187616,41.9426623]},"n1819800350":{"id":"n1819800350","loc":[-85.6012527,41.9426064]},"n1819800352":{"id":"n1819800352","loc":[-85.6214867,41.9428379]},"n1819800354":{"id":"n1819800354","loc":[-85.61338,41.94293]},"n1819800355":{"id":"n1819800355","loc":[-85.5923156,41.9428139]},"n1819800357":{"id":"n1819800357","loc":[-85.5901591,41.9453197]},"n1819800359":{"id":"n1819800359","loc":[-85.6033979,41.9408827]},"n1819800360":{"id":"n1819800360","loc":[-85.6186543,41.9414653]},"n1819800363":{"id":"n1819800363","loc":[-85.6128607,41.9425665]},"n1819800365":{"id":"n1819800365","loc":[-85.614234,41.9412977]},"n1819800367":{"id":"n1819800367","loc":[-85.6089662,41.9410902]},"n1819800369":{"id":"n1819800369","loc":[-85.6197379,41.9413695]},"n1819800370":{"id":"n1819800370","loc":[-85.6037348,41.941733]},"n1819800371":{"id":"n1819800371","loc":[-85.5993467,41.9415654]},"n1819800372":{"id":"n1819800372","loc":[-85.598077,41.94196]},"n1819800373":{"id":"n1819800373","loc":[-85.5984203,41.9394781]},"n1819800374":{"id":"n1819800374","loc":[-85.6013315,41.9427066]},"n1819800376":{"id":"n1819800376","loc":[-85.5934673,41.944167]},"n1819800378":{"id":"n1819800378","loc":[-85.6011062,41.9407753]},"n1819800379":{"id":"n1819800379","loc":[-85.6150602,41.9415131]},"n1819800380":{"id":"n1819800380","loc":[-85.6132148,41.9412338]},"n1819800381":{"id":"n1819800381","loc":[-85.5889038,41.9453835]},"n2139966621":{"id":"n2139966621","loc":[-85.6198719,41.9426184]},"n2139966622":{"id":"n2139966622","loc":[-85.6197551,41.9426123]},"n2139966623":{"id":"n2139966623","loc":[-85.6196467,41.9426279]},"n2139966624":{"id":"n2139966624","loc":[-85.6191519,41.9426221]},"n2139966625":{"id":"n2139966625","loc":[-85.6194153,41.9426256]},"n2139966626":{"id":"n2139966626","loc":[-85.6200497,41.9425812]},"n2139966629":{"id":"n2139966629","loc":[-85.6192123,41.9426229]},"n2203933101":{"id":"n2203933101","loc":[-85.6030009,41.9360592]},"w17967539":{"id":"w17967539","tags":{"highway":"residential","name":"1st Ave"},"nodes":["n185965099","n185963395","n185987021"]},"w17967751":{"id":"w17967751","tags":{"highway":"residential","name":"River St"},"nodes":["n185980088","n185988961","n185988963","n185963698"]},"w17965088":{"id":"w17965088","tags":{"highway":"residential","name":"9th St"},"nodes":["n185945133","n185964320","n185964322","n185964324","n185964326","n185964328","n185964329","n185964330","n185964331"]},"w17964467":{"id":"w17964467","tags":{"highway":"residential","name":"Mechanic St"},"nodes":["n185958030","n185958032","n185958034","n185958036"]},"w134150842":{"id":"w134150842","tags":{"bridge":"yes","highway":"residential","name":"6th St"},"nodes":["n185980090","n185980093"]},"w17966740":{"id":"w17966740","tags":{"highway":"residential","name":"6th St"},"nodes":["n185977754","n185980075","n185980077","n185980078","n185980079","n185980081","n185980083","n185980085","n185958034","n185980088","n185980090"]},"w170844765":{"id":"w170844765","tags":{"waterway":"dam"},"nodes":["n1819800304","n1819800232","n1819800325","n1819800188"]},"w17967745":{"id":"w17967745","tags":{"highway":"residential","name":"River St"},"nodes":["n185981173","n185967077","n185963099","n185958498","n185988943","n185964331","n185975332"]},"w17968113":{"id":"w17968113","tags":{"highway":"residential","name":"Green St"},"nodes":["n185988943","n185991378"]},"w134150833":{"id":"w134150833","tags":{"highway":"residential","name":"6th St"},"nodes":["n185980093","n1475283999","n185963392"]},"w17967935":{"id":"w17967935","tags":{"name":"Michigan Central Railroad","railway":"abandoned"},"nodes":["n185972757","n185990192","n185990194","n185990195","n185990196","n185990198","n185990200","n185990202","n185990204","n185990206","n185990209","n185952239","n185990211","n185990212","n185990213","n185990214","n2203933101","n185973251"]},"w17965993":{"id":"w17965993","tags":{"name":"Conrail Railroad","railway":"abandoned"},"nodes":["n185957831","n185972752","n185972754","n185972756","n185972757"]},"w17966211":{"id":"w17966211","tags":{"highway":"residential","name":"8th St"},"nodes":["n185975315","n185975316","n185954490","n185945395","n185975317","n185974509","n185945135","n185975318","n185961186","n185967634","n185975320","n185970833","n185958036","n185975325","n185975326","n185975327","n185975328","n185975330","n185975332"]},"w170844766":{"id":"w170844766","tags":{"waterway":"riverbank"},"nodes":["n1819800229","n1819800245","n2139966626","n2139966621","n2139966622","n2139966623","n1819800319","n2139966625","n2139966629","n2139966624","n1819800349","n1819800328","n1819800291","n1819800206","n1819800237","n1819800336","n1819800318","n1819800354","n1819800182","n1819800363","n1819800297","n1819800268","n1819800223","n1819800209","n1819800233","n1819800201","n1819800343","n1819800333","n1819800347","n1819800299","n1819800228","n1819800330","n1819800370","n1819800250","n1819800374","n1819800202","n1819800327","n1819800350","n1819800308","n1819800239","n1819800207","n1819800234","n1819800359","n1819800236","n1819800321","n1819800378","n1819800235","n1819800371","n1819800313","n1819800372","n1819800219","n1819800251","n1819800334","n1819800316","n1819800376","n1819800240","n1819800312","n1819800314","n1819800243","n1819800269","n1819800279","n1819800242","n1819800315","n1819800247","n1819800191","n1819800189","n1819800263","n1819800238","n1819800277","n1819800180","n1819800381","n1819800276","n1819800357","n1819800287","n1819800322","n1819800246","n1819800345","n1819800226","n1819800355","n1819800306","n1819800290","n1819800331","n1819800289","n1819800214","n1819800320","n1819800224","n1819800373","n1819800244","n1819800184","n1819800301","n1819800292","n1819800323","n1819800181","n1819800256","n1819800293","n1819800367","n1819800311","n1819800260","n1819800185","n1819800303","n1819800274","n1819800380","n1819800365","n1819800379","n1819800255","n1819800264","n1819800186","n1819800183","n1819800317","n1819800211","n1819800241","n1819800360","n1819800258","n1819800369","n1819800296","n1819800288","n1819800310","n1819800204","n1819800375","n1819800216","n1819800377","n1819800248","n1819800227","n1819800368","n1819800231","n1819800188","n1819800325","n1819800232","n1819800304","n1819800271","n1819800213","n1819800266","n1819800221","n1819800294","n1819800362","n1819800199","n1819800230","n1819800218","n1819800352","n1819800324","n1819800272","n1819800261","n1819800229"]},"n1875654132":{"id":"n1875654132","loc":[-85.6297439,41.939808]},"n1475293263":{"id":"n1475293263","loc":[-85.6296235,41.939922]},"n185947850":{"id":"n185947850","loc":[-85.631594,41.942613]},"n185952745":{"id":"n185952745","loc":[-85.630986,41.941786]},"n185972907":{"id":"n185972907","loc":[-85.631797,41.9420055]},"n185972911":{"id":"n185972911","loc":[-85.6309723,41.9411623]},"n185972915":{"id":"n185972915","loc":[-85.6295971,41.939267]},"n1475293223":{"id":"n1475293223","loc":[-85.6313962,41.9416114],"tags":{"railway":"level_crossing"}},"n1475293231":{"id":"n1475293231","loc":[-85.6318779,41.9415447]},"n1475293241":{"id":"n1475293241","loc":[-85.6304613,41.9405499]},"n1475293246":{"id":"n1475293246","loc":[-85.6297512,41.9395393],"tags":{"railway":"level_crossing"}},"n1475293251":{"id":"n1475293251","loc":[-85.6316633,41.9415128]},"n2139982404":{"id":"n2139982404","loc":[-85.6313283,41.9413748]},"n2139982407":{"id":"n2139982407","loc":[-85.6325545,41.9417787]},"n2139982408":{"id":"n2139982408","loc":[-85.6324499,41.9417693]},"n2139982409":{"id":"n2139982409","loc":[-85.6324753,41.9416444]},"n2139982410":{"id":"n2139982410","loc":[-85.6325814,41.9416538]},"n2139982411":{"id":"n2139982411","loc":[-85.6319572,41.9413515]},"n2139982412":{"id":"n2139982412","loc":[-85.6322925,41.941139]},"n2139982413":{"id":"n2139982413","loc":[-85.6323153,41.941153]},"n2139982414":{"id":"n2139982414","loc":[-85.6323019,41.9412617]},"n2139982415":{"id":"n2139982415","loc":[-85.6323703,41.9412667]},"n2139982416":{"id":"n2139982416","loc":[-85.6323555,41.941538]},"n2139982417":{"id":"n2139982417","loc":[-85.6321343,41.9416777]},"n2139982418":{"id":"n2139982418","loc":[-85.6319425,41.9416866]},"n2139982419":{"id":"n2139982419","loc":[-85.6320303,41.9416941]},"n2139982420":{"id":"n2139982420","loc":[-85.6321665,41.9415554]},"n2139982421":{"id":"n2139982421","loc":[-85.632412,41.9414164]},"n2139982422":{"id":"n2139982422","loc":[-85.6324801,41.9413421]},"n2139982423":{"id":"n2139982423","loc":[-85.6325023,41.9412585]},"n2139982424":{"id":"n2139982424","loc":[-85.6324532,41.9411607]},"n2139982425":{"id":"n2139982425","loc":[-85.6323502,41.941103]},"n2139982426":{"id":"n2139982426","loc":[-85.6322362,41.9411183]},"n2139982427":{"id":"n2139982427","loc":[-85.6318941,41.9413551]},"n2139982428":{"id":"n2139982428","loc":[-85.6318592,41.9414105]},"n2139982429":{"id":"n2139982429","loc":[-85.6320111,41.9415866]},"n2139982430":{"id":"n2139982430","loc":[-85.632446,41.9413792]},"n2139982431":{"id":"n2139982431","loc":[-85.6325112,41.941416]},"n2139982432":{"id":"n2139982432","loc":[-85.6325449,41.9416345]},"n2139982433":{"id":"n2139982433","loc":[-85.6326122,41.94164]},"n2139982434":{"id":"n2139982434","loc":[-85.6325954,41.9421966]},"n2139982435":{"id":"n2139982435","loc":[-85.6325655,41.9422411]},"n2139982436":{"id":"n2139982436","loc":[-85.632515,41.9422564]},"n2139982437":{"id":"n2139982437","loc":[-85.6324495,41.94223]},"n2139982438":{"id":"n2139982438","loc":[-85.6324009,41.9421743]},"n2139982439":{"id":"n2139982439","loc":[-85.6323915,41.9421145]},"n2139982440":{"id":"n2139982440","loc":[-85.6320287,41.9418585]},"n2139982441":{"id":"n2139982441","loc":[-85.6318285,41.9416387]},"n1475293258":{"id":"n1475293258","loc":[-85.6318289,41.9415077]},"n2168544754":{"id":"n2168544754","loc":[-85.6312814,41.9431198]},"n2168544755":{"id":"n2168544755","loc":[-85.6314212,41.9430646]},"n2168544756":{"id":"n2168544756","loc":[-85.6313387,41.942949]},"n2168544757":{"id":"n2168544757","loc":[-85.6311989,41.9430041]},"n2168544758":{"id":"n2168544758","loc":[-85.6311024,41.9429313]},"n2168544759":{"id":"n2168544759","loc":[-85.6310087,41.9428087]},"n2168544760":{"id":"n2168544760","loc":[-85.6313831,41.9426504]},"n2168544761":{"id":"n2168544761","loc":[-85.6314768,41.9427729]},"n2168544762":{"id":"n2168544762","loc":[-85.6306376,41.942809]},"n2168544763":{"id":"n2168544763","loc":[-85.6307378,41.9429427]},"n2168544764":{"id":"n2168544764","loc":[-85.630841,41.9428998]},"n2168544765":{"id":"n2168544765","loc":[-85.6307408,41.9427662]},"n2168544766":{"id":"n2168544766","loc":[-85.6305404,41.9426029]},"n2168544767":{"id":"n2168544767","loc":[-85.6304976,41.9426194]},"n2168544768":{"id":"n2168544768","loc":[-85.6305673,41.9427184]},"n2168544769":{"id":"n2168544769","loc":[-85.6306164,41.9426984]},"n2168544770":{"id":"n2168544770","loc":[-85.6306418,41.9427302]},"n2168544771":{"id":"n2168544771","loc":[-85.6306861,41.9427137]},"n2168544772":{"id":"n2168544772","loc":[-85.6307146,41.9427537]},"n2168544773":{"id":"n2168544773","loc":[-85.6308999,41.9426807]},"n2168544774":{"id":"n2168544774","loc":[-85.6308429,41.9426053]},"n2168544775":{"id":"n2168544775","loc":[-85.6308999,41.9425806]},"n2168544776":{"id":"n2168544776","loc":[-85.6308318,41.9424875]},"n2168544777":{"id":"n2168544777","loc":[-85.6307732,41.9425087]},"n2168544778":{"id":"n2168544778","loc":[-85.6307178,41.9424357]},"n2168544779":{"id":"n2168544779","loc":[-85.630485,41.942524]},"n2189099387":{"id":"n2189099387","loc":[-85.631203,41.9393371]},"n2189099404":{"id":"n2189099404","loc":[-85.6301963,41.9391363]},"n2189099405":{"id":"n2189099405","loc":[-85.6304447,41.9391352]},"n2189099406":{"id":"n2189099406","loc":[-85.6304463,41.9393391]},"n2189099407":{"id":"n2189099407","loc":[-85.6308435,41.9393373]},"n2189099408":{"id":"n2189099408","loc":[-85.6308418,41.9391251]},"n2189099409":{"id":"n2189099409","loc":[-85.6310929,41.939124]},"n2189099410":{"id":"n2189099410","loc":[-85.6310946,41.9393376]},"n2189112720":{"id":"n2189112720","loc":[-85.6314677,41.9412327]},"n2189112721":{"id":"n2189112721","loc":[-85.6313337,41.9411397]},"n2189112722":{"id":"n2189112722","loc":[-85.6320521,41.9405678]},"n2189112723":{"id":"n2189112723","loc":[-85.6321899,41.9406633]},"n2189112724":{"id":"n2189112724","loc":[-85.6313229,41.9408344]},"n2189112725":{"id":"n2189112725","loc":[-85.6311223,41.9410018]},"n2189112726":{"id":"n2189112726","loc":[-85.6313205,41.9411333]},"n2189112727":{"id":"n2189112727","loc":[-85.6315211,41.9409659]},"n2189112728":{"id":"n2189112728","loc":[-85.6311035,41.9402529]},"n2189112729":{"id":"n2189112729","loc":[-85.631226,41.9402107]},"n2189112730":{"id":"n2189112730","loc":[-85.6315966,41.9408051]},"n2189112731":{"id":"n2189112731","loc":[-85.6314741,41.9408473]},"n2189112732":{"id":"n2189112732","loc":[-85.6318114,41.940534]},"n2189112733":{"id":"n2189112733","loc":[-85.631588,41.94061]},"n2189112734":{"id":"n2189112734","loc":[-85.6314379,41.940366]},"n2189112735":{"id":"n2189112735","loc":[-85.6316613,41.94029]},"n2189112736":{"id":"n2189112736","loc":[-85.6306214,41.9400415]},"n2189112737":{"id":"n2189112737","loc":[-85.6304362,41.9397728]},"n2189112738":{"id":"n2189112738","loc":[-85.6305899,41.9397142]},"n2189112739":{"id":"n2189112739","loc":[-85.6307751,41.9399828]},"n2189112740":{"id":"n2189112740","loc":[-85.6304695,41.9401673]},"n2189112741":{"id":"n2189112741","loc":[-85.6301298,41.9396855]},"n2189112742":{"id":"n2189112742","loc":[-85.6303016,41.9396184]},"n2189112743":{"id":"n2189112743","loc":[-85.6306413,41.9401003]},"n2189112744":{"id":"n2189112744","loc":[-85.6309656,41.9406189]},"n2189112745":{"id":"n2189112745","loc":[-85.6308738,41.940493]},"n2189112746":{"id":"n2189112746","loc":[-85.6309333,41.940469]},"n2189112747":{"id":"n2189112747","loc":[-85.6307634,41.9402358]},"n2189112748":{"id":"n2189112748","loc":[-85.6308798,41.9401889]},"n2189112749":{"id":"n2189112749","loc":[-85.6311416,41.940548]},"n2189112750":{"id":"n2189112750","loc":[-85.6309577,41.9408708]},"n2189112751":{"id":"n2189112751","loc":[-85.630874,41.9407777]},"n2189112752":{"id":"n2189112752","loc":[-85.6310622,41.9406841]},"n2189112753":{"id":"n2189112753","loc":[-85.6311459,41.9407772]},"n2189112754":{"id":"n2189112754","loc":[-85.6320308,41.9405747]},"n2189112755":{"id":"n2189112755","loc":[-85.6317769,41.9401857]},"n2189112756":{"id":"n2189112756","loc":[-85.6313462,41.9401785]},"n2189112757":{"id":"n2189112757","loc":[-85.6313423,41.9401199]},"n2189112758":{"id":"n2189112758","loc":[-85.6318308,41.9401184]},"n2189112759":{"id":"n2189112759","loc":[-85.6321154,41.9405433]},"n2189112760":{"id":"n2189112760","loc":[-85.6310307,41.941683]},"n2189112761":{"id":"n2189112761","loc":[-85.6309808,41.9416078]},"n2189112762":{"id":"n2189112762","loc":[-85.6312094,41.9415156]},"n2189112763":{"id":"n2189112763","loc":[-85.6312636,41.9415865]},"n2189112764":{"id":"n2189112764","loc":[-85.6309384,41.94155]},"n2189112765":{"id":"n2189112765","loc":[-85.631156,41.9414619]},"n2189112766":{"id":"n2189112766","loc":[-85.6311968,41.94152]},"n2189112767":{"id":"n2189112767","loc":[-85.6308946,41.9414851]},"n2189112768":{"id":"n2189112768","loc":[-85.6308237,41.9413888]},"n2189112769":{"id":"n2189112769","loc":[-85.6309858,41.9413228]},"n2189112770":{"id":"n2189112770","loc":[-85.6310567,41.9414192]},"n2189112771":{"id":"n2189112771","loc":[-85.6307774,41.9413276]},"n2189112772":{"id":"n2189112772","loc":[-85.6309068,41.9412735]},"n2189112773":{"id":"n2189112773","loc":[-85.6309531,41.9413347]},"n2189112774":{"id":"n2189112774","loc":[-85.6307975,41.9412466]},"n2189112775":{"id":"n2189112775","loc":[-85.6307006,41.9411699]},"n2189112776":{"id":"n2189112776","loc":[-85.6308289,41.941113]},"n2189112777":{"id":"n2189112777","loc":[-85.6308997,41.9412012]},"n2189112778":{"id":"n2189112778","loc":[-85.630765,41.9412062]},"n2189112779":{"id":"n2189112779","loc":[-85.630739,41.9412177]},"n2189112780":{"id":"n2189112780","loc":[-85.6305822,41.9410391]},"n2189112781":{"id":"n2189112781","loc":[-85.6304117,41.9408177]},"n2189112782":{"id":"n2189112782","loc":[-85.6305086,41.9407769]},"n2189112783":{"id":"n2189112783","loc":[-85.6306779,41.9410044]},"n2189112784":{"id":"n2189112784","loc":[-85.6307734,41.9421663]},"n2189112785":{"id":"n2189112785","loc":[-85.630708,41.9420741]},"n2189112786":{"id":"n2189112786","loc":[-85.630863,41.9420133]},"n2189112787":{"id":"n2189112787","loc":[-85.6309285,41.9421055]},"n2189112788":{"id":"n2189112788","loc":[-85.6307014,41.9420263]},"n2189112789":{"id":"n2189112789","loc":[-85.6306648,41.941971]},"n2189112790":{"id":"n2189112790","loc":[-85.6307927,41.9419178]},"n2189112791":{"id":"n2189112791","loc":[-85.6308366,41.9419696]},"n2189112792":{"id":"n2189112792","loc":[-85.6307574,41.9418708]},"n2189112793":{"id":"n2189112793","loc":[-85.6306288,41.9419231]},"n2189112794":{"id":"n2189112794","loc":[-85.6306943,41.9417835]},"n2189112795":{"id":"n2189112795","loc":[-85.6305344,41.9418474]},"n2189112796":{"id":"n2189112796","loc":[-85.6305981,41.9419355]},"n2189123410":{"id":"n2189123410","loc":[-85.6315476,41.9393801]},"n2189123412":{"id":"n2189123412","loc":[-85.6315247,41.9399188]},"n2189123415":{"id":"n2189123415","loc":[-85.6316484,41.9400433]},"n185945138":{"id":"n185945138","loc":[-85.627073,41.93319]},"n185945142":{"id":"n185945142","loc":[-85.6296891,41.9331674]},"n185945401":{"id":"n185945401","loc":[-85.6269,41.930199]},"n185945405":{"id":"n185945405","loc":[-85.6296598,41.9301676]},"n185956891":{"id":"n185956891","loc":[-85.6251617,41.9255049]},"n185959979":{"id":"n185959979","loc":[-85.626333,41.928347]},"n185959983":{"id":"n185959983","loc":[-85.6296419,41.9283288]},"n185961192":{"id":"n185961192","loc":[-85.627053,41.9352031]},"n185961200":{"id":"n185961200","loc":[-85.6297088,41.9351902]},"n185963655":{"id":"n185963655","loc":[-85.6296112,41.9273948]},"n185963665":{"id":"n185963665","loc":[-85.626047,41.92737]},"n185963688":{"id":"n185963688","loc":[-85.6296503,41.9292199]},"n185963689":{"id":"n185963689","loc":[-85.6296694,41.931157]},"n185963690":{"id":"n185963690","loc":[-85.6296791,41.9321485]},"n185963691":{"id":"n185963691","loc":[-85.6296991,41.9341973]},"n185967638":{"id":"n185967638","loc":[-85.627089,41.9361884]},"n185972917":{"id":"n185972917","loc":[-85.6293759,41.9388605]},"n185972919":{"id":"n185972919","loc":[-85.6290337,41.9380234]},"n185972921":{"id":"n185972921","loc":[-85.628424,41.936212]},"n185972923":{"id":"n185972923","loc":[-85.628367,41.936029]},"n185974511":{"id":"n185974511","loc":[-85.627064,41.932169]},"n185977728":{"id":"n185977728","loc":[-85.625605,41.925842]},"n185977729":{"id":"n185977729","loc":[-85.625685,41.926163]},"n185977731":{"id":"n185977731","loc":[-85.6257845,41.9264872]},"n185977733":{"id":"n185977733","loc":[-85.62663,41.929251]},"n185977734":{"id":"n185977734","loc":[-85.627008,41.930642]},"n185977736":{"id":"n185977736","loc":[-85.627029,41.930775]},"n185977738":{"id":"n185977738","loc":[-85.627041,41.930946]},"n185977739":{"id":"n185977739","loc":[-85.6270379,41.9311746]},"n185977742":{"id":"n185977742","loc":[-85.627055,41.934206]},"n185977744":{"id":"n185977744","loc":[-85.627084,41.936804]},"n185977746":{"id":"n185977746","loc":[-85.627104,41.936914]},"n185977748":{"id":"n185977748","loc":[-85.627156,41.937026]},"n185977750":{"id":"n185977750","loc":[-85.6272406,41.9371672]},"n185977752":{"id":"n185977752","loc":[-85.627317,41.93723]},"n185977753":{"id":"n185977753","loc":[-85.627422,41.937312]},"n185977755":{"id":"n185977755","loc":[-85.627754,41.937504]},"n185977757":{"id":"n185977757","loc":[-85.627883,41.937623]},"n185977761":{"id":"n185977761","loc":[-85.627984,41.93773]},"n1475283996":{"id":"n1475283996","loc":[-85.6270514,41.9317122],"tags":{"railway":"level_crossing"}},"n1475284004":{"id":"n1475284004","loc":[-85.6278177,41.9342117],"tags":{"railway":"level_crossing"}},"n1475284014":{"id":"n1475284014","loc":[-85.6251877,41.9255913],"tags":{"railway":"level_crossing"}},"n1475284017":{"id":"n1475284017","loc":[-85.6274992,41.9331816],"tags":{"railway":"level_crossing"}},"n1475284021":{"id":"n1475284021","loc":[-85.6297108,41.9353939],"tags":{"railway":"level_crossing"}},"n1475284027":{"id":"n1475284027","loc":[-85.62811,41.935198],"tags":{"railway":"level_crossing"}},"n1475284035":{"id":"n1475284035","loc":[-85.626888,41.9311757],"tags":{"railway":"level_crossing"}},"n1475293245":{"id":"n1475293245","loc":[-85.6286047,41.9367881]},"n1875654302":{"id":"n1875654302","loc":[-85.6296367,41.927491]},"n2189099388":{"id":"n2189099388","loc":[-85.6312007,41.9389988]},"n2189099389":{"id":"n2189099389","loc":[-85.6311003,41.9389992]},"n2189099390":{"id":"n2189099390","loc":[-85.6310988,41.9387847]},"n2189099391":{"id":"n2189099391","loc":[-85.6312165,41.9387843]},"n2189099392":{"id":"n2189099392","loc":[-85.6312152,41.9385857]},"n2189099393":{"id":"n2189099393","loc":[-85.6310877,41.9385862]},"n2189099394":{"id":"n2189099394","loc":[-85.6310858,41.9383161]},"n2189099395":{"id":"n2189099395","loc":[-85.6302002,41.9383196]},"n2189099396":{"id":"n2189099396","loc":[-85.6302011,41.9384472]},"n2189099397":{"id":"n2189099397","loc":[-85.6301018,41.9384476]},"n2189099398":{"id":"n2189099398","loc":[-85.6301025,41.9385419]},"n2189099399":{"id":"n2189099399","loc":[-85.6299275,41.9385427]},"n2189099400":{"id":"n2189099400","loc":[-85.62993,41.9388653]},"n2189099401":{"id":"n2189099401","loc":[-85.630107,41.9388645]},"n2189099402":{"id":"n2189099402","loc":[-85.6301079,41.9389908]},"n2189099403":{"id":"n2189099403","loc":[-85.6301951,41.9389904]},"n2189123382":{"id":"n2189123382","loc":[-85.6336279,41.9354365]},"n2189123384":{"id":"n2189123384","loc":[-85.6328492,41.9355177]},"n2189123387":{"id":"n2189123387","loc":[-85.6323762,41.9357396]},"n2189123388":{"id":"n2189123388","loc":[-85.6315174,41.9358966]},"n2189123389":{"id":"n2189123389","loc":[-85.6304331,41.936124]},"n2189123390":{"id":"n2189123390","loc":[-85.6302075,41.9364271]},"n2189123391":{"id":"n2189123391","loc":[-85.6303458,41.9367953]},"n2189123392":{"id":"n2189123392","loc":[-85.6299601,41.9369739]},"n2189123393":{"id":"n2189123393","loc":[-85.6299164,41.9374882]},"n2189123394":{"id":"n2189123394","loc":[-85.6299455,41.9378022]},"n2189123395":{"id":"n2189123395","loc":[-85.6299771,41.9379053]},"n2189123396":{"id":"n2189123396","loc":[-85.6301597,41.9379091]},"n2189123397":{"id":"n2189123397","loc":[-85.6308042,41.9377913]},"n2189123398":{"id":"n2189123398","loc":[-85.6316885,41.9378082]},"n2189123399":{"id":"n2189123399","loc":[-85.6316848,41.9380079]},"n2189123400":{"id":"n2189123400","loc":[-85.6318449,41.9381161]},"n2189123401":{"id":"n2189123401","loc":[-85.6320705,41.9381811]},"n2189123402":{"id":"n2189123402","loc":[-85.6321433,41.9383706]},"n2189123404":{"id":"n2189123404","loc":[-85.632056,41.9384355]},"n2189123406":{"id":"n2189123406","loc":[-85.6317867,41.9384572]},"n2189123409":{"id":"n2189123409","loc":[-85.6316572,41.9387281]},"n2189123417":{"id":"n2189123417","loc":[-85.6315946,41.93775]},"n2189123419":{"id":"n2189123419","loc":[-85.6302641,41.9378393]},"w208640158":{"id":"w208640158","tags":{"area":"yes","natural":"wetland"},"nodes":["n2189123379","n2189123382","n2189123384","n2189123387","n2189123388","n2189123389","n2189123390","n2189123391","n2189123392","n2189123393","n2189123394","n2189123395","n2189123396","n2189123419","n2189123397","n2189123417","n2189123398","n2189123399","n2189123400","n2189123401","n2189123402","n2189123404","n2189123406","n2189123409","n2189123410","n2189123412","n2189123415","n1819805722","n1819805861","n1819805887","n1819805760","n1819805641","n1819805632","n2189123379"]},"w134150787":{"id":"w134150787","tags":{"name":"Conrail Railroad","railway":"rail"},"nodes":["n185972905","n185972907","n1475293223","n185972911","n1475293241","n1475293246","n185972915","n185972917","n185972919","n1475293245","n185972921","n185972923","n1475284027","n1475284004","n1475284017","n1475283996","n1475284035","n1475284014","n185956891"]},"w208639443":{"id":"w208639443","tags":{"area":"yes","building":"yes"},"nodes":["n2189112720","n2189112721","n2189112722","n2189112723","n2189112720"]},"w17966462":{"id":"w17966462","tags":{"highway":"secondary","name":"South Main Street","old_ref":"US 131","ref":"M 86"},"nodes":["n185977728","n185977729","n185977731","n185963665","n185959979","n185977733","n185945401","n185977734","n185977736","n185977738","n185977739","n1475283996","n185974511","n185945138","n185977742","n185961192","n185967638","n185977744","n185977746","n185977748","n185977750","n185977752","n185977753","n185977754","n185977755","n185977757","n185977761","n185958030","n1475293263","n185963698","n185952745","n185947850","n185977762"]},"w203985741":{"id":"w203985741","tags":{"area":"yes","leisure":"park","name":"Conservation Park"},"nodes":["n2139982404","n2139982405","n2139982399","n2139982400","n1819805770","n2139982402","n2139982403","n2139982401","n1819805780","n1819805834","n2139982406","n2139982404"]},"w17963676":{"id":"w17963676","tags":{"highway":"service"},"nodes":["n1475293258","n2139982428","n2139982427","n2139982426","n2139982425","n2139982424","n2139982423","n2139982422","n2139982430","n2139982421","n2139982420","n2139982429","n1475293231","n1475293258","n1475293251","n1475293223","n185952745"]},"w203985745":{"id":"w203985745","tags":{"highway":"footway"},"nodes":["n2139982430","n2139982431","n2139982432","n2139982433","n2139982434","n2139982435","n2139982436","n2139982437","n2139982438","n2139982439","n2139982440","n2139982441","n1475293231"]},"w208639451":{"id":"w208639451","tags":{"area":"yes","building":"yes"},"nodes":["n2189112754","n2189112755","n2189112756","n2189112757","n2189112758","n2189112759","n2189112754"]},"w208639452":{"id":"w208639452","tags":{"area":"yes","building":"yes"},"nodes":["n2189112760","n2189112761","n2189112766","n2189112762","n2189112763","n2189112760"]},"w206805244":{"id":"w206805244","tags":{"area":"yes","building":"yes"},"nodes":["n2168544766","n2168544767","n2168544768","n2168544769","n2168544770","n2168544771","n2168544772","n2168544773","n2168544774","n2168544775","n2168544776","n2168544777","n2168544778","n2168544779","n2168544766"]},"w208639444":{"id":"w208639444","tags":{"area":"yes","building":"yes"},"nodes":["n2189112724","n2189112725","n2189112726","n2189112727","n2189112724"]},"w208639450":{"id":"w208639450","tags":{"area":"yes","building":"yes"},"nodes":["n2189112750","n2189112751","n2189112752","n2189112753","n2189112750"]},"w208639448":{"id":"w208639448","tags":{"area":"yes","building":"yes"},"nodes":["n2189112740","n2189112741","n2189112742","n2189112743","n2189112740"]},"w208637859":{"id":"w208637859","tags":{"area":"yes","building":"yes"},"nodes":["n2189099387","n2189099388","n2189099389","n2189099390","n2189099391","n2189099392","n2189099393","n2189099394","n2189099395","n2189099396","n2189099397","n2189099398","n2189099399","n2189099400","n2189099401","n2189099402","n2189099403","n2189099404","n2189099405","n2189099406","n2189099407","n2189099408","n2189099409","n2189099410","n2189099387"]},"w208639453":{"id":"w208639453","tags":{"area":"yes","building":"yes"},"nodes":["n2189112764","n2189112765","n2189112766","n2189112761","n2189112764"]},"w208639456":{"id":"w208639456","tags":{"area":"yes","building":"yes"},"nodes":["n2189112774","n2189112778","n2189112779","n2189112775","n2189112776","n2189112777","n2189112774"]},"w208639445":{"id":"w208639445","tags":{"area":"yes","building":"yes"},"nodes":["n2189112728","n2189112729","n2189112730","n2189112731","n2189112728"]},"w17967776":{"id":"w17967776","tags":{"highway":"residential","name":"5th St"},"nodes":["n185958032","n185988963"]},"w208639461":{"id":"w208639461","tags":{"area":"yes","building":"yes"},"nodes":["n2189112792","n2189112794","n2189112795","n2189112796","n2189112793","n2189112792"]},"w206805241":{"id":"w206805241","tags":{"area":"yes","building":"yes"},"nodes":["n2168544754","n2168544755","n2168544756","n2168544757","n2168544754"]},"w208639449":{"id":"w208639449","tags":{"area":"yes","building":"yes"},"nodes":["n2189112744","n2189112745","n2189112746","n2189112747","n2189112748","n2189112749","n2189112744"]},"w208639455":{"id":"w208639455","tags":{"area":"yes","building":"yes"},"nodes":["n2189112771","n2189112772","n2189112773","n2189112768","n2189112771"]},"w208639457":{"id":"w208639457","tags":{"area":"yes","building":"yes"},"nodes":["n2189112780","n2189112781","n2189112782","n2189112783","n2189112780"]},"w208639446":{"id":"w208639446","tags":{"area":"yes","building":"yes"},"nodes":["n2189112732","n2189112733","n2189112734","n2189112735","n2189112732"]},"w208639454":{"id":"w208639454","tags":{"area":"yes","building":"yes"},"nodes":["n2189112767","n2189112768","n2189112773","n2189112769","n2189112770","n2189112767"]},"w203985743":{"id":"w203985743","tags":{"amenity":"parking","area":"yes"},"nodes":["n2139982411","n2139982412","n2139982413","n2139982414","n2139982415","n2139982416","n2139982417","n2139982419","n2139982418","n2139982411"]},"w17965023":{"id":"w17965023","tags":{"highway":"residential","name":"4th St"},"nodes":["n185963655","n1875654302","n185959983","n185963688","n185945405","n185963689","n185963690","n185945142","n185963691","n185961200","n1475284021","n1475293246","n1875654132","n1475293263"]},"w206805242":{"id":"w206805242","tags":{"area":"yes","building":"yes"},"nodes":["n2168544758","n2168544759","n2168544760","n2168544761","n2168544758"]},"w208639460":{"id":"w208639460","tags":{"area":"yes","building":"yes"},"nodes":["n2189112792","n2189112793","n2189112789","n2189112790","n2189112792"]},"w208639447":{"id":"w208639447","tags":{"area":"yes","building":"yes"},"nodes":["n2189112736","n2189112737","n2189112738","n2189112739","n2189112736"]},"w208639458":{"id":"w208639458","tags":{"area":"yes","building":"yes"},"nodes":["n2189112784","n2189112785","n2189112786","n2189112787","n2189112784"]},"w203985744":{"id":"w203985744","tags":{"highway":"service"},"nodes":["n2139982425","n2139982400"]},"w208639459":{"id":"w208639459","tags":{"area":"yes","building":"yes"},"nodes":["n2189112788","n2189112789","n2189112790","n2189112791","n2189112788"]},"w203985742":{"id":"w203985742","tags":{"amenity":"shelter","area":"yes","shelter_type":"picnic_shelter"},"nodes":["n2139982407","n2139982408","n2139982409","n2139982410","n2139982407"]},"w206805243":{"id":"w206805243","tags":{"area":"yes","building":"yes"},"nodes":["n2168544762","n2168544763","n2168544764","n2168544765","n2168544762"]},"n185959081":{"id":"n185959081","loc":[-85.628469,41.948674]},"n185967427":{"id":"n185967427","loc":[-85.632054,41.951174]},"n185967424":{"id":"n185967424","loc":[-85.6320391,41.9499109]},"n185968101":{"id":"n185968101","loc":[-85.6308395,41.9511969]},"n185960792":{"id":"n185960792","loc":[-85.632074,41.953707]},"n185961389":{"id":"n185961389","loc":[-85.630935,41.959037]},"n185961391":{"id":"n185961391","loc":[-85.632169,41.959025]},"n185965395":{"id":"n185965395","loc":[-85.63216,41.959859]},"n185966953":{"id":"n185966953","loc":[-85.630894,41.957428]},"n185966955":{"id":"n185966955","loc":[-85.632122,41.957427]},"n185967430":{"id":"n185967430","loc":[-85.632077,41.952453]},"n185967432":{"id":"n185967432","loc":[-85.632095,41.954685]},"n185967434":{"id":"n185967434","loc":[-85.632121,41.955914]},"n185967436":{"id":"n185967436","loc":[-85.632128,41.9583]},"n185967438":{"id":"n185967438","loc":[-85.632187,41.960681]},"n185967440":{"id":"n185967440","loc":[-85.632182,41.961493]},"n185968102":{"id":"n185968102","loc":[-85.630855,41.952452]},"n185968104":{"id":"n185968104","loc":[-85.630887,41.953714]},"n185968106":{"id":"n185968106","loc":[-85.630883,41.954692]},"n185968108":{"id":"n185968108","loc":[-85.630904,41.955913]},"n185968110":{"id":"n185968110","loc":[-85.630904,41.958058]},"n185968112":{"id":"n185968112","loc":[-85.630952,41.960667]},"n185968114":{"id":"n185968114","loc":[-85.630972,41.961495]},"n185968116":{"id":"n185968116","loc":[-85.630962,41.961967]},"n185978969":{"id":"n185978969","loc":[-85.633214,41.948618]},"n185985812":{"id":"n185985812","loc":[-85.633274,41.951159]},"n185986155":{"id":"n185986155","loc":[-85.633258,41.949893]},"n2208608826":{"id":"n2208608826","loc":[-85.6339222,41.9486225]},"w17964531":{"id":"w17964531","tags":{"highway":"residential","name":"Willow Dr"},"nodes":["n185959079","n185959081"]},"w17967386":{"id":"w17967386","tags":{"highway":"residential","name":"East Armitage Street"},"nodes":["n185982195","n185968101","n185967427","n185985812","n185974583"]},"w17965502":{"id":"w17965502","tags":{"highway":"residential","name":"Elm Street"},"nodes":["n185968100","n185968101","n185968102","n185968104","n185968106","n185968108","n185966953","n185968110","n185961389","n185968112","n185968114","n185968116"]},"w17967844":{"id":"w17967844","tags":{"highway":"residential","name":"East Bennett Street"},"nodes":["n185982193","n185967424","n185986155","n185978390"]},"w17966581":{"id":"w17966581","tags":{"highway":"residential","name":"E Kelsey St"},"nodes":["n185978967","n185978969","n2208608826","n185971578"]},"w17965402":{"id":"w17965402","tags":{"highway":"residential","name":"Walnut Street"},"nodes":["n185967422","n185967424","n185967427","n185967430","n185960792","n185967432","n185967434","n185966955","n185967436","n185961391","n185965395","n185967438","n185967440"]},"n2199093506":{"id":"n2199093506","loc":[-85.6251879,41.9478322]},"n2199093505":{"id":"n2199093505","loc":[-85.6252076,41.9477749]},"n2199093504":{"id":"n2199093504","loc":[-85.6252289,41.9477602]},"n2199093503":{"id":"n2199093503","loc":[-85.625201,41.9477492]},"n2199093502":{"id":"n2199093502","loc":[-85.6251682,41.9477066]},"n2199093501":{"id":"n2199093501","loc":[-85.6251715,41.947609]},"n2199093500":{"id":"n2199093500","loc":[-85.6252125,41.9475639]},"n2199093499":{"id":"n2199093499","loc":[-85.6252896,41.9475602]},"n2199093498":{"id":"n2199093498","loc":[-85.6253027,41.9475334]},"n2199093497":{"id":"n2199093497","loc":[-85.6253437,41.9474822]},"n2199093496":{"id":"n2199093496","loc":[-85.6254421,41.9474675]},"n2199093495":{"id":"n2199093495","loc":[-85.6256503,41.9474944]},"n2199093494":{"id":"n2199093494","loc":[-85.6257257,41.9476127]},"n2199093493":{"id":"n2199093493","loc":[-85.6257028,41.9477285]},"n2199093492":{"id":"n2199093492","loc":[-85.6255339,41.9478102]},"n2199093491":{"id":"n2199093491","loc":[-85.6253912,41.9478224]},"n2199093490":{"id":"n2199093490","loc":[-85.6253043,41.947859]},"n2199093489":{"id":"n2199093489","loc":[-85.6252027,41.9478846]},"n2199093458":{"id":"n2199093458","loc":[-85.6246876,41.9486617]},"n2199093457":{"id":"n2199093457","loc":[-85.6243127,41.9486583]},"n2199093456":{"id":"n2199093456","loc":[-85.624306,41.9490569]},"n2199093455":{"id":"n2199093455","loc":[-85.624681,41.9490603]},"n2199093514":{"id":"n2199093514","loc":[-85.6236228,41.9496059]},"n2199093513":{"id":"n2199093513","loc":[-85.6236231,41.9496997]},"n2199093512":{"id":"n2199093512","loc":[-85.623357,41.9497002]},"n2199093511":{"id":"n2199093511","loc":[-85.6233567,41.9496136]},"n2199093508":{"id":"n2199093508","loc":[-85.6239735,41.9494287]},"n2199093507":{"id":"n2199093507","loc":[-85.6239741,41.9496052]},"n2199093488":{"id":"n2199093488","loc":[-85.624497,41.9512286]},"n2199093487":{"id":"n2199093487","loc":[-85.6244966,41.9511259]},"n2199093486":{"id":"n2199093486","loc":[-85.6243151,41.9511263]},"n2199093485":{"id":"n2199093485","loc":[-85.6243154,41.951229]},"n2199093484":{"id":"n2199093484","loc":[-85.6241205,41.9508665]},"n2199093483":{"id":"n2199093483","loc":[-85.624115,41.9505249]},"n2199093482":{"id":"n2199093482","loc":[-85.6243149,41.9505231]},"n2199093481":{"id":"n2199093481","loc":[-85.6243203,41.9508648]},"n2199093480":{"id":"n2199093480","loc":[-85.624393,41.9508668]},"n2199093479":{"id":"n2199093479","loc":[-85.6243904,41.9505956]},"n2199093478":{"id":"n2199093478","loc":[-85.6246727,41.950594]},"n2199093477":{"id":"n2199093477","loc":[-85.624675,41.9508203]},"n2199093476":{"id":"n2199093476","loc":[-85.6245097,41.9508212]},"n2199093475":{"id":"n2199093475","loc":[-85.6245101,41.9508662]},"n2199093474":{"id":"n2199093474","loc":[-85.6241008,41.9493459]},"n2199093473":{"id":"n2199093473","loc":[-85.6242442,41.9493459]},"n2199093472":{"id":"n2199093472","loc":[-85.6242442,41.9493681]},"n2199093471":{"id":"n2199093471","loc":[-85.6243397,41.9493681]},"n2199093470":{"id":"n2199093470","loc":[-85.6243417,41.9493511]},"n2199093469":{"id":"n2199093469","loc":[-85.6247251,41.9493485]},"n2199093468":{"id":"n2199093468","loc":[-85.6247548,41.9504949]},"n2199093467":{"id":"n2199093467","loc":[-85.6241214,41.9505017]},"n2199093466":{"id":"n2199093466","loc":[-85.6254398,41.950174]},"n2199093465":{"id":"n2199093465","loc":[-85.6254412,41.9499872]},"n2199093464":{"id":"n2199093464","loc":[-85.6255363,41.9499876]},"n2199093463":{"id":"n2199093463","loc":[-85.6255374,41.9498439]},"n2199093462":{"id":"n2199093462","loc":[-85.6255638,41.949844]},"n2199093461":{"id":"n2199093461","loc":[-85.6255652,41.9496672]},"n2199093460":{"id":"n2199093460","loc":[-85.6251823,41.9496656]},"n2199093459":{"id":"n2199093459","loc":[-85.6251785,41.9501729]},"n2199093510":{"id":"n2199093510","loc":[-85.6229922,41.9496143]},"n2199093509":{"id":"n2199093509","loc":[-85.6229915,41.9494306]},"n185948903":{"id":"n185948903","loc":[-85.616514,41.947449]},"n185955120":{"id":"n185955120","loc":[-85.620103,41.951]},"n185955143":{"id":"n185955143","loc":[-85.619784,41.94746]},"n185960124":{"id":"n185960124","loc":[-85.615238,41.947468]},"n185961362":{"id":"n185961362","loc":[-85.617437,41.947451]},"n185961364":{"id":"n185961364","loc":[-85.61861,41.947456]},"n185961367":{"id":"n185961367","loc":[-85.620088,41.947458]},"n185965105":{"id":"n185965105","loc":[-85.620087,41.94924]},"n185970220":{"id":"n185970220","loc":[-85.62156,41.948333]},"n185974697":{"id":"n185974697","loc":[-85.6201059,41.950132]},"n2138420778":{"id":"n2138420778","loc":[-85.616948,41.9474499]},"w17967535":{"id":"w17967535","tags":{"highway":"residential","name":"10th Ave"},"nodes":["n185955120","n185986812","n185983141"]},"w209716130":{"id":"w209716130","tags":{"area":"yes","building":"yes"},"nodes":["n2199093485","n2199093486","n2199093487","n2199093488","n2199093485"]},"w17964788":{"id":"w17964788","tags":{"highway":"residential","name":"6th Ave"},"nodes":["n185960124","n185948903","n2138420778","n185961362","n185961364","n185955143","n185961367","n185961369","n185961371"]},"w17965159":{"id":"w17965159","tags":{"highway":"residential","name":"8th Ave"},"nodes":["n185965105","n185965108","n185965110"]},"w209716125":{"id":"w209716125","tags":{"area":"yes","building":"yes"},"nodes":["n2199093459","n2199093460","n2199093461","n2199093462","n2199093463","n2199093464","n2199093465","n2199093466","n2199093459"]},"w17965699":{"id":"w17965699","tags":{"highway":"residential","name":"7th Ave"},"nodes":["n185970220","n185970222","n185970224"]},"w209716132":{"id":"w209716132","tags":{"area":"yes","building":"yes"},"nodes":["n2199093507","n2199093508","n2199093509","n2199093510","n2199093511","n2199093512","n2199093513","n2199093514","n2199093507"]},"w17966129":{"id":"w17966129","tags":{"highway":"residential","name":"9th Ave"},"nodes":["n185974697","n185974699"]},"w209716127":{"id":"w209716127","tags":{"area":"yes","building":"yes"},"nodes":["n2199093475","n2199093476","n2199093477","n2199093478","n2199093479","n2199093480","n2199093475"]},"w209716131":{"id":"w209716131","tags":{"area":"yes","natural":"water","water":"pond"},"nodes":["n2199093489","n2199093490","n2199093491","n2199093492","n2199093493","n2199093494","n2199093495","n2199093496","n2199093497","n2199093498","n2199093499","n2199093500","n2199093501","n2199093502","n2199093503","n2199093504","n2199093505","n2199093506","n2199093489"]},"w209716126":{"id":"w209716126","tags":{"area":"yes","building":"yes"},"nodes":["n2199093467","n2199093468","n2199093469","n2199093470","n2199093471","n2199093472","n2199093473","n2199093474","n2199093467"]},"w209716124":{"id":"w209716124","tags":{"area":"yes","building":"yes"},"nodes":["n2199093455","n2199093456","n2199093457","n2199093458","n2199093455"]},"w209716128":{"id":"w209716128","tags":{"area":"yes","building":"yes"},"nodes":["n2199093481","n2199093482","n2199093483","n2199093484","n2199093481"]},"n185949872":{"id":"n185949872","loc":[-85.643009,41.949264]},"n185949875":{"id":"n185949875","loc":[-85.642598,41.94929]},"n185949877":{"id":"n185949877","loc":[-85.642127,41.949382]},"n185949881":{"id":"n185949881","loc":[-85.64169,41.949936]},"n185988165":{"id":"n185988165","loc":[-85.642167,41.947657]},"n185988167":{"id":"n185988167","loc":[-85.642347,41.947662]},"n185988169":{"id":"n185988169","loc":[-85.642621,41.947659]},"n185965019":{"id":"n185965019","loc":[-85.6385084,41.951127]},"n1475293248":{"id":"n1475293248","loc":[-85.6386095,41.9512214]},"n185962639":{"id":"n185962639","loc":[-85.649669,41.949161]},"n185962810":{"id":"n185962810","loc":[-85.649907,41.949157]},"n185964355":{"id":"n185964355","loc":[-85.637412,41.9511359]},"n185965021":{"id":"n185965021","loc":[-85.638661,41.952386]},"n185965023":{"id":"n185965023","loc":[-85.638654,41.953665]},"n185965025":{"id":"n185965025","loc":[-85.638694,41.954649]},"n185965027":{"id":"n185965027","loc":[-85.638724,41.955913]},"n185971415":{"id":"n185971415","loc":[-85.644466,41.949246]},"n185971417":{"id":"n185971417","loc":[-85.647021,41.949193]},"n185971420":{"id":"n185971420","loc":[-85.648476,41.949169]},"n185979975":{"id":"n185979975","loc":[-85.644429,41.947633]},"n185988171":{"id":"n185988171","loc":[-85.645377,41.947622]},"w17963211":{"id":"w17963211","tags":{"highway":"residential"},"nodes":["n185949870","n185949872","n185949875","n185949877","n185949881"]},"w17965839":{"id":"w17965839","tags":{"highway":"residential","name":"Arnold St"},"nodes":["n185949870","n185971415","n185971417","n185971420","n185962639","n185962810"]},"w17967618":{"id":"w17967618","tags":{"highway":"residential","name":"Pierson St"},"nodes":["n185967777","n185988165","n185988167","n185988169","n185985824","n185979975","n185988171"]},"w17965149":{"id":"w17965149","tags":{"highway":"residential","name":"Oak St"},"nodes":["n185965019","n1475293248","n185965021","n185965023","n185965025","n185965027"]},"w17966118":{"id":"w17966118","tags":{"highway":"residential","name":"West Armitage Street"},"nodes":["n185974583","n185974585","n185964355","n185965019"]},"n2208608800":{"id":"n2208608800","loc":[-85.6354294,41.9486201]},"n2199109806":{"id":"n2199109806","loc":[-85.6350474,41.9477884]},"n2199109804":{"id":"n2199109804","loc":[-85.6350476,41.9477962]},"n2199109802":{"id":"n2199109802","loc":[-85.635002,41.9477969]},"n2199109799":{"id":"n2199109799","loc":[-85.6350018,41.9477883]},"n2199109797":{"id":"n2199109797","loc":[-85.6349141,41.9477897]},"n2199109795":{"id":"n2199109795","loc":[-85.6349131,41.9477535]},"n2199109793":{"id":"n2199109793","loc":[-85.6349395,41.9477531]},"n2199109791":{"id":"n2199109791","loc":[-85.6349382,41.9477077]},"n2199109789":{"id":"n2199109789","loc":[-85.6351236,41.9477049]},"n2199109787":{"id":"n2199109787","loc":[-85.6351259,41.9477872]},"n2199109785":{"id":"n2199109785","loc":[-85.634972,41.9475992]},"n2199109783":{"id":"n2199109783","loc":[-85.6349206,41.9475997]},"n2199109770":{"id":"n2199109770","loc":[-85.6348499,41.9475461]},"n2199109768":{"id":"n2199109768","loc":[-85.6348499,41.9475084]},"n2199109765":{"id":"n2199109765","loc":[-85.6349241,41.9474569]},"n2199109763":{"id":"n2199109763","loc":[-85.634967,41.9474564]},"n2199109762":{"id":"n2199109762","loc":[-85.6350405,41.9475121]},"n2199109761":{"id":"n2199109761","loc":[-85.6350405,41.9475419]},"n2199109753":{"id":"n2199109753","loc":[-85.6342443,41.9478391]},"n2199109751":{"id":"n2199109751","loc":[-85.6342427,41.9477927]},"n2199109745":{"id":"n2199109745","loc":[-85.6342439,41.9476859]},"n2199109743":{"id":"n2199109743","loc":[-85.6342429,41.9476575]},"n2199109741":{"id":"n2199109741","loc":[-85.6344615,41.9476533]},"n2199109739":{"id":"n2199109739","loc":[-85.6344678,41.9478348]},"n2199109737":{"id":"n2199109737","loc":[-85.634416,41.9480059]},"n2199109735":{"id":"n2199109735","loc":[-85.6344145,41.9478983]},"n2199109733":{"id":"n2199109733","loc":[-85.6342749,41.9478993]},"n2199109731":{"id":"n2199109731","loc":[-85.6342753,41.9479272]},"n2199109729":{"id":"n2199109729","loc":[-85.6342498,41.9479274]},"n2199109727":{"id":"n2199109727","loc":[-85.6342505,41.9479762]},"n2199109725":{"id":"n2199109725","loc":[-85.6342743,41.947976]},"n2199109723":{"id":"n2199109723","loc":[-85.6342747,41.948007]},"n2199109721":{"id":"n2199109721","loc":[-85.6343415,41.9476355]},"n2199109719":{"id":"n2199109719","loc":[-85.6343391,41.9474973]},"n2199109717":{"id":"n2199109717","loc":[-85.6343133,41.9474798]},"n2199109715":{"id":"n2199109715","loc":[-85.6342874,41.9474737]},"n2199109709":{"id":"n2199109709","loc":[-85.6349804,41.94815]},"n2199109707":{"id":"n2199109707","loc":[-85.6348915,41.9481505]},"n2199109705":{"id":"n2199109705","loc":[-85.6348917,41.9481692]},"n2199109702":{"id":"n2199109702","loc":[-85.6348522,41.9481694]},"n2199109700":{"id":"n2199109700","loc":[-85.6348532,41.9482679]},"n2199109698":{"id":"n2199109698","loc":[-85.6348315,41.948268]},"n2199109696":{"id":"n2199109696","loc":[-85.6348318,41.9482955]},"n2199109694":{"id":"n2199109694","loc":[-85.6349653,41.9482946]},"n2199109692":{"id":"n2199109692","loc":[-85.6349656,41.9483211]},"n2199109690":{"id":"n2199109690","loc":[-85.634999,41.9483209]},"n2199109688":{"id":"n2199109688","loc":[-85.6349987,41.9482947]},"n2199109686":{"id":"n2199109686","loc":[-85.6351753,41.9482935]},"n2199109684":{"id":"n2199109684","loc":[-85.6351749,41.9482617]},"n2199109682":{"id":"n2199109682","loc":[-85.6351588,41.9482618]},"n2199109680":{"id":"n2199109680","loc":[-85.6351575,41.9481518]},"n2199109678":{"id":"n2199109678","loc":[-85.6350671,41.9481524]},"n2199109676":{"id":"n2199109676","loc":[-85.6350649,41.9479659]},"n2199109674":{"id":"n2199109674","loc":[-85.6349785,41.9479665]},"n2199109671":{"id":"n2199109671","loc":[-85.6343069,41.9483263]},"n2199109669":{"id":"n2199109669","loc":[-85.6343052,41.9482981]},"n2199109658":{"id":"n2199109658","loc":[-85.6343314,41.9480549]},"n2199109656":{"id":"n2199109656","loc":[-85.6343305,41.9480461]},"n2199109654":{"id":"n2199109654","loc":[-85.634435,41.9480468]},"n2199109652":{"id":"n2199109652","loc":[-85.6344342,41.9483746]},"n2199109650":{"id":"n2199109650","loc":[-85.6344629,41.9483727]},"n2199109648":{"id":"n2199109648","loc":[-85.6344637,41.9484561]},"n2199109645":{"id":"n2199109645","loc":[-85.63443,41.9484567]},"n2199109642":{"id":"n2199109642","loc":[-85.6344317,41.948505]},"n185964352":{"id":"n185964352","loc":[-85.6373958,41.9489943]},"n185964351":{"id":"n185964351","loc":[-85.637113,41.9486]},"n2208608825":{"id":"n2208608825","loc":[-85.6354483,41.9494241]},"n2208608823":{"id":"n2208608823","loc":[-85.6360418,41.949416]},"n2208608821":{"id":"n2208608821","loc":[-85.6360458,41.9495802]},"n2208608811":{"id":"n2208608811","loc":[-85.6357458,41.9495843]},"n2208608808":{"id":"n2208608808","loc":[-85.6357508,41.9497835]},"n2208608806":{"id":"n2208608806","loc":[-85.6354573,41.9497875]},"n2208608795":{"id":"n2208608795","loc":[-85.6354595,41.9498778]},"n2199109638":{"id":"n2199109638","loc":[-85.6349605,41.949749]},"n2199109636":{"id":"n2199109636","loc":[-85.6349605,41.9497639]},"n2199109634":{"id":"n2199109634","loc":[-85.6349061,41.94971]},"n2199109632":{"id":"n2199109632","loc":[-85.6349048,41.9496569]},"n2199109630":{"id":"n2199109630","loc":[-85.6348835,41.9496571]},"n2199109628":{"id":"n2199109628","loc":[-85.6348829,41.9497103]},"n2199109626":{"id":"n2199109626","loc":[-85.635227,41.9497738]},"n2199109624":{"id":"n2199109624","loc":[-85.6352184,41.9497787]},"n2199109622":{"id":"n2199109622","loc":[-85.6351181,41.9497806]},"n2199109620":{"id":"n2199109620","loc":[-85.6351181,41.9497456]},"n2199109618":{"id":"n2199109618","loc":[-85.6348842,41.9497651]},"n2199109616":{"id":"n2199109616","loc":[-85.6348827,41.9496238]},"n2199109615":{"id":"n2199109615","loc":[-85.6351268,41.9496206]},"n2199109614":{"id":"n2199109614","loc":[-85.6351261,41.9495891]},"n2199109613":{"id":"n2199109613","loc":[-85.6351957,41.9495881]},"n2199109612":{"id":"n2199109612","loc":[-85.6351924,41.9494515]},"n2199109611":{"id":"n2199109611","loc":[-85.6353997,41.9494488]},"n2199109610":{"id":"n2199109610","loc":[-85.6354074,41.9497715]},"n2189015681":{"id":"n2189015681","loc":[-85.6344229,41.9509639]},"n2189015677":{"id":"n2189015677","loc":[-85.634424,41.9507396]},"n2138493843":{"id":"n2138493843","loc":[-85.6343935,41.9502836]},"n2138493840":{"id":"n2138493840","loc":[-85.634398,41.9506264]},"n354002838":{"id":"n354002838","loc":[-85.6345197,41.9510631]},"n2114807590":{"id":"n2114807590","loc":[-85.634511,41.9499767]},"n185964353":{"id":"n185964353","loc":[-85.6374092,41.9498755]},"n1819849180":{"id":"n1819849180","loc":[-85.6348236,41.94996]},"n1819849115":{"id":"n1819849115","loc":[-85.6354372,41.9499538]},"n1819848921":{"id":"n1819848921","loc":[-85.6348439,41.951064]},"n1819848885":{"id":"n1819848885","loc":[-85.6354575,41.9510578]},"n185984281":{"id":"n185984281","loc":[-85.638075,41.949872]},"n2208608827":{"id":"n2208608827","loc":[-85.6339169,41.9473191]},"n2199109749":{"id":"n2199109749","loc":[-85.6342082,41.9477934]},"n2199109747":{"id":"n2199109747","loc":[-85.6342045,41.9476867]},"n2199109713":{"id":"n2199109713","loc":[-85.6342404,41.9474746]},"n2199109711":{"id":"n2199109711","loc":[-85.6342404,41.9476355]},"n2199109673":{"id":"n2199109673","loc":[-85.6340886,41.9483282]},"n2199109667":{"id":"n2199109667","loc":[-85.6342403,41.9482988]},"n2199109665":{"id":"n2199109665","loc":[-85.6342386,41.9482116]},"n2199109662":{"id":"n2199109662","loc":[-85.6340861,41.9482135]},"n2199109660":{"id":"n2199109660","loc":[-85.6340802,41.9480562]},"n2199109640":{"id":"n2199109640","loc":[-85.6340928,41.9485063]},"n354031366":{"id":"n354031366","loc":[-85.6341667,41.9477778],"tags":{"amenity":"place_of_worship","name":"Faith Tabernacle Church","religion":"christian"}},"n2189015686":{"id":"n2189015686","loc":[-85.6337798,41.95099]},"n2189015684":{"id":"n2189015684","loc":[-85.6337794,41.9509674]},"n2189015673":{"id":"n2189015673","loc":[-85.6337501,41.9507457]},"n2189015669":{"id":"n2189015669","loc":[-85.6337501,41.9506974]},"n2189015665":{"id":"n2189015665","loc":[-85.6339034,41.9506959]},"n2189015662":{"id":"n2189015662","loc":[-85.6339015,41.950436]},"n2189015658":{"id":"n2189015658","loc":[-85.6334916,41.9504376]},"n2189015655":{"id":"n2189015655","loc":[-85.6334939,41.9507558]},"n2189015650":{"id":"n2189015650","loc":[-85.6334543,41.950756]},"n2189015649":{"id":"n2189015649","loc":[-85.633456,41.9509915]},"n2138493842":{"id":"n2138493842","loc":[-85.6339937,41.9502836]},"n2138493841":{"id":"n2138493841","loc":[-85.6339983,41.9506281]},"n2114807579":{"id":"n2114807579","loc":[-85.6333644,41.9510682]},"n2114807573":{"id":"n2114807573","loc":[-85.6333557,41.9499819]},"n354031330":{"id":"n354031330","loc":[-85.6341667,41.9497222],"tags":{"amenity":"place_of_worship","name":"Trinity Episcopal Church","religion":"christian"}},"n185960794":{"id":"n185960794","loc":[-85.633307,41.9537]},"n185964357":{"id":"n185964357","loc":[-85.637432,41.952399]},"n185964358":{"id":"n185964358","loc":[-85.637452,41.953665]},"n185964359":{"id":"n185964359","loc":[-85.63746,41.954658]},"n185964360":{"id":"n185964360","loc":[-85.637473,41.95592]},"n185964361":{"id":"n185964361","loc":[-85.637468,41.956906]},"n185964362":{"id":"n185964362","loc":[-85.637483,41.958313]},"n185966957":{"id":"n185966957","loc":[-85.633361,41.957422]},"n185975351":{"id":"n185975351","loc":[-85.63334,41.9559]},"n185978784":{"id":"n185978784","loc":[-85.633311,41.954679]},"n185986157":{"id":"n185986157","loc":[-85.633287,41.952426]},"n185986158":{"id":"n185986158","loc":[-85.6333607,41.9582301],"tags":{"highway":"turning_circle"}},"w17965182":{"id":"w17965182","tags":{"highway":"residential","name":"W Prutzman St"},"nodes":["n185965289","n2189153241","n185965291"]},"w208627205":{"id":"w208627205","tags":{"area":"yes","building":"yes"},"nodes":["n2189015649","n2189015650","n2189015655","n2189015658","n2189015662","n2189015665","n2189015669","n2189015673","n2189015677","n2189015681","n2189015684","n2189015686","n2189015649"]},"w209717042":{"id":"w209717042","tags":{"amenity":"place_of_worship","area":"yes","building":"yes","denomination":"presbyterian","name":"First Presbyterian Church","religion":"christian"},"nodes":["n2199109610","n2199109611","n2199109612","n2199109613","n2199109614","n2199109615","n2199109616","n2199109630","n2199109632","n2199109634","n2199109628","n2199109618","n2199109636","n2199109638","n2199109620","n2199109622","n2199109624","n2199109626","n2199109610"]},"w209717045":{"id":"w209717045","tags":{"area":"yes","building":"yes"},"nodes":["n2199109711","n2199109713","n2199109715","n2199109717","n2199109719","n2199109721","n2199109711"]},"w209717047":{"id":"w209717047","tags":{"area":"yes","building":"yes"},"nodes":["n2199109739","n2199109741","n2199109743","n2199109745","n2199109747","n2199109749","n2199109751","n2199109753","n2199109739"]},"w209717044":{"id":"w209717044","tags":{"area":"yes","building":"yes"},"nodes":["n2199109674","n2199109676","n2199109678","n2199109680","n2199109682","n2199109684","n2199109686","n2199109688","n2199109690","n2199109692","n2199109694","n2199109696","n2199109698","n2199109700","n2199109702","n2199109705","n2199109707","n2199109709","n2199109674"]},"w210822776":{"id":"w210822776","tags":{"highway":"service","service":"alley","surface":"unpaved"},"nodes":["n2208608795","n2208608806","n2208608825","n2208608800","n2189153241"]},"w210822778":{"id":"w210822778","tags":{"highway":"service","service":"alley"},"nodes":["n2208608826","n2208608827"]},"w209717050":{"id":"w209717050","tags":{"area":"yes","building":"yes"},"nodes":["n2199109787","n2199109789","n2199109791","n2199109793","n2199109795","n2199109797","n2199109799","n2199109802","n2199109804","n2199109806","n2199109787"]},"w17965097":{"id":"w17965097","tags":{"highway":"residential","name":"Maple Street"},"nodes":["n185964351","n185964352","n185964353","n185964355","n185964357","n185964358","n185964359","n185964360","n185964361","n185964362"]},"w17965856":{"id":"w17965856","tags":{"highway":"residential","name":"W Kelsey St"},"nodes":["n185971578","n2208608800","n185971580","n185964351"]},"w17967444":{"id":"w17967444","tags":{"highway":"residential","name":"East Street"},"nodes":["n185966937","n185978969","n185986155","n185985812","n185986157","n185960794","n185978784","n185975351","n185966957","n185986158"]},"w17967764":{"id":"w17967764","tags":{"highway":"residential","name":"Rock River Ave"},"nodes":["n185984017","n185964351"]},"w170848329":{"id":"w170848329","tags":{"leisure":"park","name":"LaFayette Park"},"nodes":["n1819849180","n1819849115","n1819848885","n1819848921","n1819849180"]},"w17967208":{"id":"w17967208","tags":{"highway":"residential","name":"West Bennett Street"},"nodes":["n185978390","n2208608795","n185984020","n185964353","n185984281"]},"w17965349":{"id":"w17965349","tags":{"highway":"residential","name":"E Prutzman St"},"nodes":["n185966937","n2208608827","n185965289"]},"w209717049":{"id":"w209717049","tags":{"area":"yes","building":"yes"},"nodes":["n2199109761","n2199109762","n2199109763","n2199109765","n2199109768","n2199109770","n2199109783","n2199109785","n2199109761"]},"w203841840":{"id":"w203841840","tags":{"area":"yes","leisure":"playground"},"nodes":["n2138493840","n2138493841","n2138493842","n2138493843","n2138493840"]},"w209717043":{"id":"w209717043","tags":{"amenity":"place_of_worship","area":"yes","building":"church","denomination":"methodist","name":"First United Methodist Church","religion":"christian"},"nodes":["n2199109640","n2199109642","n2199109645","n2199109648","n2199109650","n2199109652","n2199109654","n2199109656","n2199109658","n2199109660","n2199109662","n2199109665","n2199109667","n2199109669","n2199109671","n2199109673","n2199109640"]},"w201484341":{"id":"w201484341","tags":{"amenity":"school","name":"Hoppin School"},"nodes":["n354002838","n2114807579","n2114807573","n2114807590","n354002838"]},"w209717046":{"id":"w209717046","tags":{"area":"yes","building":"yes"},"nodes":["n2199109723","n2199109725","n2199109727","n2199109729","n2199109731","n2199109733","n2199109735","n2199109737","n2199109723"]},"w210822777":{"id":"w210822777","tags":{"amenity":"parking","area":"yes"},"nodes":["n2208608806","n2208608808","n2208608811","n2208608821","n2208608823","n2208608825","n2208608806"]},"n185954965":{"id":"n185954965","loc":[-85.6191189,41.9441922]},"n185954968":{"id":"n185954968","loc":[-85.6194384,41.9442405]},"n185954970":{"id":"n185954970","loc":[-85.6196543,41.9443252]},"n185954972":{"id":"n185954972","loc":[-85.6197862,41.9444539]},"n354002931":{"id":"n354002931","loc":[-85.6198991,41.9455269]},"n354030853":{"id":"n354030853","loc":[-85.6219444,41.9455556],"tags":{"amenity":"place_of_worship","name":"Grant Chapel","religion":"christian"}},"n367815963":{"id":"n367815963","loc":[-85.6202778,41.9461111],"tags":{"building":"yes","name":"George Washington Carver Community Center"}},"n185947331":{"id":"n185947331","loc":[-85.618779,41.943269]},"n185947333":{"id":"n185947333","loc":[-85.618795,41.943511]},"n185947336":{"id":"n185947336","loc":[-85.618711,41.94413]},"n185947338":{"id":"n185947338","loc":[-85.618704,41.944189]},"n185947339":{"id":"n185947339","loc":[-85.618597,41.944337]},"n185947340":{"id":"n185947340","loc":[-85.618485,41.944528]},"n185947343":{"id":"n185947343","loc":[-85.618442,41.944716]},"n185947345":{"id":"n185947345","loc":[-85.618457,41.945107]},"n185947347":{"id":"n185947347","loc":[-85.618296,41.945338]},"n185947374":{"id":"n185947374","loc":[-85.616748,41.944453]},"n185947375":{"id":"n185947375","loc":[-85.616813,41.944646]},"n185947376":{"id":"n185947376","loc":[-85.616859,41.945196]},"n185947377":{"id":"n185947377","loc":[-85.616941,41.945352]},"n185947406":{"id":"n185947406","loc":[-85.618184,41.944227]},"n185947409":{"id":"n185947409","loc":[-85.617911,41.943875]},"n185947410":{"id":"n185947410","loc":[-85.617579,41.943682]},"n185947411":{"id":"n185947411","loc":[-85.61713,41.943589]},"n185947412":{"id":"n185947412","loc":[-85.616549,41.943559]},"n185947414":{"id":"n185947414","loc":[-85.616482,41.943556]},"n185947464":{"id":"n185947464","loc":[-85.616526,41.943788]},"n185947466":{"id":"n185947466","loc":[-85.616504,41.944002]},"n185948863":{"id":"n185948863","loc":[-85.619017,41.943391]},"n185948865":{"id":"n185948865","loc":[-85.619059,41.943368]},"n185955022":{"id":"n185955022","loc":[-85.620088,41.945571]},"n185955025":{"id":"n185955025","loc":[-85.620051,41.945505]},"n185955028":{"id":"n185955028","loc":[-85.62001,41.94541]},"n185980371":{"id":"n185980371","loc":[-85.620982,41.944742]},"n185980398":{"id":"n185980398","loc":[-85.621305,41.944782]},"n185980401":{"id":"n185980401","loc":[-85.621174,41.944819]},"n185980403":{"id":"n185980403","loc":[-85.621029,41.944871]},"n185980405":{"id":"n185980405","loc":[-85.620741,41.945011]},"n185980407":{"id":"n185980407","loc":[-85.620616,41.945085]},"n185980409":{"id":"n185980409","loc":[-85.620506,41.945172]},"n185980411":{"id":"n185980411","loc":[-85.620394,41.945273]},"n185980413":{"id":"n185980413","loc":[-85.620316,41.94536]},"n185980415":{"id":"n185980415","loc":[-85.620257,41.945452]},"n185980417":{"id":"n185980417","loc":[-85.620212,41.945535]},"n185985910":{"id":"n185985910","loc":[-85.620101,41.945811]},"n185985912":{"id":"n185985912","loc":[-85.620081,41.945937]},"n1475283972":{"id":"n1475283972","loc":[-85.6198991,41.9437179]},"n1475283982":{"id":"n1475283982","loc":[-85.6195022,41.9433463]},"n1475284007":{"id":"n1475284007","loc":[-85.6193037,41.9433383]},"n1475284040":{"id":"n1475284040","loc":[-85.6197329,41.9434121]},"n1475284044":{"id":"n1475284044","loc":[-85.6198756,41.9435363]},"n1475284050":{"id":"n1475284050","loc":[-85.6199689,41.9432106]},"n1475284053":{"id":"n1475284053","loc":[-85.6198943,41.9432921]},"n185954974":{"id":"n185954974","loc":[-85.6198296,41.94473]},"n185954977":{"id":"n185954977","loc":[-85.6200474,41.9447384]},"n2196831365":{"id":"n2196831365","loc":[-85.6202259,41.9460883]},"n2196831366":{"id":"n2196831366","loc":[-85.6202245,41.9458642]},"n2196831367":{"id":"n2196831367","loc":[-85.6205184,41.9458631]},"n2196831368":{"id":"n2196831368","loc":[-85.6205189,41.9459437]},"n2196831369":{"id":"n2196831369","loc":[-85.6203879,41.9459441]},"n2196831370":{"id":"n2196831370","loc":[-85.6203888,41.9460878]},"n2196831371":{"id":"n2196831371","loc":[-85.6184046,41.9465663]},"n2196831372":{"id":"n2196831372","loc":[-85.6191563,41.9465618]},"n2196831373":{"id":"n2196831373","loc":[-85.6191536,41.946319]},"n2196831374":{"id":"n2196831374","loc":[-85.6187356,41.9463216]},"n2196831375":{"id":"n2196831375","loc":[-85.6187334,41.9461197]},"n2196831376":{"id":"n2196831376","loc":[-85.6193167,41.9461162]},"n2196831377":{"id":"n2196831377","loc":[-85.6193156,41.9460229]},"n2196831378":{"id":"n2196831378","loc":[-85.619622,41.946021]},"n2196831379":{"id":"n2196831379","loc":[-85.6196237,41.9461712]},"n2196831380":{"id":"n2196831380","loc":[-85.6197702,41.9461703]},"n2196831381":{"id":"n2196831381","loc":[-85.6197685,41.9460202]},"n2196831382":{"id":"n2196831382","loc":[-85.6197323,41.9460204]},"n2196831383":{"id":"n2196831383","loc":[-85.6197305,41.9458563]},"n2196831384":{"id":"n2196831384","loc":[-85.6196165,41.945857]},"n2196831385":{"id":"n2196831385","loc":[-85.6196156,41.9457764]},"n2196831386":{"id":"n2196831386","loc":[-85.6194472,41.9457775]},"n2196831387":{"id":"n2196831387","loc":[-85.6194151,41.9457777]},"n2196831388":{"id":"n2196831388","loc":[-85.6183779,41.9457883]},"n2196831389":{"id":"n2196831389","loc":[-85.6183842,41.9461317]},"n2196831390":{"id":"n2196831390","loc":[-85.6185026,41.9461304]},"n2196831391":{"id":"n2196831391","loc":[-85.6185061,41.9463194]},"n2196831392":{"id":"n2196831392","loc":[-85.6184001,41.9463205]},"n2196831393":{"id":"n2196831393","loc":[-85.6182482,41.9464163]},"n2196831394":{"id":"n2196831394","loc":[-85.6182467,41.9463193]},"n2196831395":{"id":"n2196831395","loc":[-85.6180389,41.946321]},"n2196831397":{"id":"n2196831397","loc":[-85.6180404,41.946418]},"n185947303":{"id":"n185947303","loc":[-85.611074,41.943389]},"n185947304":{"id":"n185947304","loc":[-85.611332,41.943267]},"n185947305":{"id":"n185947305","loc":[-85.611635,41.943218]},"n185947306":{"id":"n185947306","loc":[-85.612762,41.943311]},"n185947308":{"id":"n185947308","loc":[-85.613027,41.943327]},"n185947310":{"id":"n185947310","loc":[-85.615377,41.942996]},"n185947312":{"id":"n185947312","loc":[-85.615701,41.943007]},"n185947314":{"id":"n185947314","loc":[-85.61604,41.943067]},"n185947315":{"id":"n185947315","loc":[-85.61626,41.943083]},"n185947316":{"id":"n185947316","loc":[-85.616507,41.943048]},"n185947319":{"id":"n185947319","loc":[-85.616702,41.94299]},"n185947321":{"id":"n185947321","loc":[-85.617078,41.942918]},"n185947322":{"id":"n185947322","loc":[-85.617366,41.942973]},"n185947323":{"id":"n185947323","loc":[-85.617601,41.943033]},"n185947325":{"id":"n185947325","loc":[-85.617799,41.943027]},"n185947327":{"id":"n185947327","loc":[-85.618264,41.942961]},"n185947328":{"id":"n185947328","loc":[-85.618508,41.942972]},"n185947329":{"id":"n185947329","loc":[-85.618707,41.943076]},"n185947361":{"id":"n185947361","loc":[-85.615356,41.944922]},"n185947363":{"id":"n185947363","loc":[-85.61536,41.944893]},"n185947365":{"id":"n185947365","loc":[-85.615406,41.944547]},"n185947367":{"id":"n185947367","loc":[-85.61548,41.944351]},"n185947369":{"id":"n185947369","loc":[-85.615805,41.94419]},"n185947371":{"id":"n185947371","loc":[-85.616166,41.944156]},"n185947373":{"id":"n185947373","loc":[-85.616411,41.944197]},"n185947416":{"id":"n185947416","loc":[-85.616335,41.94343]},"n185947417":{"id":"n185947417","loc":[-85.616069,41.943293]},"n185947419":{"id":"n185947419","loc":[-85.615803,41.943249]},"n185947420":{"id":"n185947420","loc":[-85.615524,41.943342]},"n185947421":{"id":"n185947421","loc":[-85.615311,41.94353]},"n185947422":{"id":"n185947422","loc":[-85.614338,41.943558]},"n185947423":{"id":"n185947423","loc":[-85.61422,41.94369]},"n185947425":{"id":"n185947425","loc":[-85.614221,41.944224]},"n185947427":{"id":"n185947427","loc":[-85.614198,41.944888]},"n185947429":{"id":"n185947429","loc":[-85.614221,41.945439]},"n185947468":{"id":"n185947468","loc":[-85.615908,41.944756]},"n185947470":{"id":"n185947470","loc":[-85.615871,41.944888]},"n185947472":{"id":"n185947472","loc":[-85.615878,41.94507]},"n185955153":{"id":"n185955153","loc":[-85.620087,41.947701]},"n185960690":{"id":"n185960690","loc":[-85.620141,41.951901]},"n185978817":{"id":"n185978817","loc":[-85.617193,41.954706]},"n185985916":{"id":"n185985916","loc":[-85.620088,41.94758]},"n185985918":{"id":"n185985918","loc":[-85.620133,41.951538]},"n185985919":{"id":"n185985919","loc":[-85.62013,41.952104]},"n185985920":{"id":"n185985920","loc":[-85.620104,41.952305]},"n185985921":{"id":"n185985921","loc":[-85.620062,41.952499]},"n185985922":{"id":"n185985922","loc":[-85.619993,41.952702]},"n185985925":{"id":"n185985925","loc":[-85.619879,41.952986]},"n185985927":{"id":"n185985927","loc":[-85.619689,41.95329]},"n185985928":{"id":"n185985928","loc":[-85.619508,41.953521]},"n185985929":{"id":"n185985929","loc":[-85.619286,41.953728]},"n185985930":{"id":"n185985930","loc":[-85.618925,41.954007]},"n185985931":{"id":"n185985931","loc":[-85.618638,41.954189]},"n185985932":{"id":"n185985932","loc":[-85.61831,41.954358]},"n185985934":{"id":"n185985934","loc":[-85.618015,41.954485]},"n185985936":{"id":"n185985936","loc":[-85.617606,41.954611]},"n1475283975":{"id":"n1475283975","loc":[-85.6150935,41.9434118]},"n1475283979":{"id":"n1475283979","loc":[-85.6193367,41.9430252]},"n1475283989":{"id":"n1475283989","loc":[-85.6104771,41.9455269]},"n1475283990":{"id":"n1475283990","loc":[-85.6104771,41.9437179]},"n1475283994":{"id":"n1475283994","loc":[-85.6198042,41.9429763]},"n1475283998":{"id":"n1475283998","loc":[-85.6192101,41.9426716]},"n1475284000":{"id":"n1475284000","loc":[-85.6198622,41.942836]},"n1475284002":{"id":"n1475284002","loc":[-85.6163262,41.9427688]},"n1475284006":{"id":"n1475284006","loc":[-85.6179527,41.9429168]},"n1475284029":{"id":"n1475284029","loc":[-85.6197195,41.9427278]},"n1475284038":{"id":"n1475284038","loc":[-85.6194405,41.9427837]},"n1475284052":{"id":"n1475284052","loc":[-85.6153225,41.942841]},"n1475284055":{"id":"n1475284055","loc":[-85.6129233,41.9437179]},"n2139966627":{"id":"n2139966627","loc":[-85.61958,41.9427558]},"w17966773":{"id":"w17966773","tags":{"highway":"secondary","name":"E Michigan Ave","ref":"M 60"},"nodes":["n185980372","n185980398","n185980401","n185980403","n185980405","n185980407","n185980409","n185980411","n185980413","n185980415","n185980417","n185955019"]},"w17964043":{"id":"w17964043","tags":{"highway":"residential"},"nodes":["n185955019","n185955022","n185955025","n185955028","n185954977","n185971477","n1475284050","n1475284000","n1475284029","n2139966627","n1475284038"]},"w17962834":{"id":"w17962834","tags":{"highway":"service"},"nodes":["n185947316","n185947414","n185947464","n185947466","n185947373","n185947468","n185947470","n185947472","n185947474"]},"w209470310":{"id":"w209470310","tags":{"area":"yes","building":"yes"},"nodes":["n2196831393","n2196831394","n2196831395","n2196831397","n2196831393"]},"w17963058":{"id":"w17963058","tags":{"highway":"service"},"nodes":["n185947333","n185948863","n185948865","n1475284007","n1475283982","n1475284040","n1475284044"]},"w17962823":{"id":"w17962823","tags":{"highway":"service"},"nodes":["n185947359","n185947361","n185947363","n185947365","n185947367","n185947369","n185947371","n185947373","n185947374","n185947375","n185947376","n185947377","n185947378"]},"w17962821":{"id":"w17962821","tags":{"highway":"service"},"nodes":["n185947303","n185947304","n185947305","n185947306","n185947308","n185947310","n185947312","n185947314","n185947315","n185947316","n185947319","n185947321","n185947322","n185947323","n185947325","n185947327","n185947328","n185947329","n185947331","n185947333","n185947336","n185947338","n185947339","n185947340","n185947343","n185947345","n185947347","n185947349"]},"w134150798":{"id":"w134150798","tags":{"amenity":"grave_yard","name":"Riverside Cemetery"},"nodes":["n354002931","n1475283972","n1475284053","n1475283994","n1475283979","n1475283998","n1475284006","n1475284002","n1475284052","n1475283975","n1475284055","n1475283990","n1475283989","n354002931"]},"w17964040":{"id":"w17964040","tags":{"highway":"service"},"nodes":["n185947336","n185954965","n185954968","n185954970","n185954972","n185954974","n185954977"]},"w209470308":{"id":"w209470308","tags":{"area":"yes","building":"yes"},"nodes":["n2196831365","n2196831366","n2196831367","n2196831368","n2196831369","n2196831370","n2196831365"]},"w17962828":{"id":"w17962828","tags":{"highway":"service"},"nodes":["n185947340","n185947406","n185947409","n185947410","n185947411","n185947412","n185947414","n185947416","n185947417","n185947419","n185947420","n185947421","n185947422","n185947423","n185947425","n185947427","n185947429"]},"w209470309":{"id":"w209470309","tags":{"area":"yes","building":"yes"},"nodes":["n2196831371","n2196831372","n2196831373","n2196831374","n2196831375","n2196831376","n2196831377","n2196831378","n2196831379","n2196831380","n2196831381","n2196831382","n2196831383","n2196831384","n2196831385","n2196831386","n2196831387","n2196831388","n2196831389","n2196831390","n2196831391","n2196831392","n2196831371"]},"w17967415":{"id":"w17967415","tags":{"highway":"secondary","name":"Jefferson St","name_1":"State Highway 60","ref":"M 60"},"nodes":["n185955019","n185985910","n185985912","n185985914","n185961367","n185985916","n185955153","n185965105","n185974697","n185955120","n185985918","n185960690","n185985919","n185985920","n185985921","n185985922","n185985925","n185985927","n185985928","n185985929","n185985930","n185985931","n185985932","n185985934","n185985936","n185978817"]},"w17966772":{"id":"w17966772","tags":{"highway":"unclassified","name":"E Michigan Ave","name_1":"State Highway 60"},"nodes":["n185954977","n185980371","n185980372"]},"n185958500":{"id":"n185958500","loc":[-85.621591,41.941075]},"n185963110":{"id":"n185963110","loc":[-85.6204416,41.9408882]},"n2139966628":{"id":"n2139966628","loc":[-85.6196431,41.9426467],"tags":{"leisure":"fishing"}},"n2139966630":{"id":"n2139966630","loc":[-85.6199354,41.9429616]},"n2199127051":{"id":"n2199127051","loc":[-85.6170556,41.939696]},"n2199127052":{"id":"n2199127052","loc":[-85.6170536,41.9392909]},"n2199127053":{"id":"n2199127053","loc":[-85.6172067,41.9392905]},"n2199127054":{"id":"n2199127054","loc":[-85.6172061,41.9391853]},"n2199127055":{"id":"n2199127055","loc":[-85.6171481,41.9391854]},"n2199127060":{"id":"n2199127060","loc":[-85.6167389,41.9392896]},"n2199127061":{"id":"n2199127061","loc":[-85.6168728,41.9392892]},"n2199127062":{"id":"n2199127062","loc":[-85.6168747,41.9396965]},"n2199127071":{"id":"n2199127071","loc":[-85.620196,41.9399446]},"n2199127072":{"id":"n2199127072","loc":[-85.620193,41.9397316]},"n2199127073":{"id":"n2199127073","loc":[-85.6200381,41.9397328]},"n2199127074":{"id":"n2199127074","loc":[-85.6200412,41.9399458]},"n2199127075":{"id":"n2199127075","loc":[-85.6203606,41.9399939]},"n2199127076":{"id":"n2199127076","loc":[-85.6205527,41.9399922]},"n2199127077":{"id":"n2199127077","loc":[-85.6205482,41.9397115]},"n2199127078":{"id":"n2199127078","loc":[-85.6204132,41.9397124]},"n2199127079":{"id":"n2199127079","loc":[-85.6204144,41.9396341]},"n2199127080":{"id":"n2199127080","loc":[-85.6205699,41.9396324]},"n2199127081":{"id":"n2199127081","loc":[-85.6205722,41.939498]},"n2199127082":{"id":"n2199127082","loc":[-85.6204064,41.9394997]},"n2199127083":{"id":"n2199127083","loc":[-85.6204087,41.939561]},"n2199127084":{"id":"n2199127084","loc":[-85.6203103,41.9395618]},"n2199127085":{"id":"n2199127085","loc":[-85.620308,41.9396069]},"n2199127086":{"id":"n2199127086","loc":[-85.6200347,41.9396086]},"n2199127087":{"id":"n2199127087","loc":[-85.6200382,41.9397141]},"n2199127088":{"id":"n2199127088","loc":[-85.6202257,41.9397149]},"n2199127089":{"id":"n2199127089","loc":[-85.6202269,41.9399182]},"n2199127090":{"id":"n2199127090","loc":[-85.6203595,41.9399199]},"n2199127091":{"id":"n2199127091","loc":[-85.6212335,41.939688]},"n2199127092":{"id":"n2199127092","loc":[-85.6212328,41.939595]},"n2199127093":{"id":"n2199127093","loc":[-85.6208807,41.9395966]},"n2199127094":{"id":"n2199127094","loc":[-85.6208815,41.9396896]},"n2199127095":{"id":"n2199127095","loc":[-85.6208676,41.9396872]},"n2199127096":{"id":"n2199127096","loc":[-85.6208583,41.9393539]},"n2199127097":{"id":"n2199127097","loc":[-85.6207006,41.9393563]},"n2199127098":{"id":"n2199127098","loc":[-85.6207099,41.9396896]},"n185967054":{"id":"n185967054","loc":[-85.6173384,41.9356126]},"n185967063":{"id":"n185967063","loc":[-85.617371,41.936243]},"n185967065":{"id":"n185967065","loc":[-85.617337,41.936299]},"n185967068":{"id":"n185967068","loc":[-85.617321,41.936373]},"n185967070":{"id":"n185967070","loc":[-85.6173562,41.9366969]},"n185967074":{"id":"n185967074","loc":[-85.6173635,41.9377414]},"n185967075":{"id":"n185967075","loc":[-85.6173696,41.9381886]},"n185967076":{"id":"n185967076","loc":[-85.617372,41.938535]},"n2199127056":{"id":"n2199127056","loc":[-85.617147,41.9389616]},"n2199127057":{"id":"n2199127057","loc":[-85.6172136,41.9389614]},"n2199127058":{"id":"n2199127058","loc":[-85.6172123,41.9386909]},"n2199127059":{"id":"n2199127059","loc":[-85.616736,41.9386922]},"n2203921041":{"id":"n2203921041","loc":[-85.6173018,41.9346369]},"w203983952":{"id":"w203983952","tags":{"highway":"service"},"nodes":["n2139966627","n1819800319"]},"w209718301":{"id":"w209718301","tags":{"area":"yes","building":"yes"},"nodes":["n2199127051","n2199127052","n2199127053","n2199127054","n2199127055","n2199127056","n2199127057","n2199127058","n2199127059","n2199127060","n2199127061","n2199127062","n2199127051"]},"w209718304":{"id":"w209718304","tags":{"area":"yes","building":"yes"},"nodes":["n2199127071","n2199127072","n2199127073","n2199127074","n2199127071"]},"w17964961":{"id":"w17964961","tags":{"highway":"residential","name":"Whipple St"},"nodes":["n185963099","n185963110"]},"w17964489":{"id":"w17964489","tags":{"highway":"residential","name":"Jackson St"},"nodes":["n185958498","n185958500"]},"w203983953":{"id":"w203983953","tags":{"area":"yes","leisure":"park","name":"Marina Park"},"nodes":["n1475283994","n1475283979","n1475283998","n2139966629","n2139966625","n1819800319","n2139966623","n2139966622","n2139966621","n2139966630","n1475283994"]},"w17965366":{"id":"w17965366","tags":{"highway":"residential","name":"14th St"},"nodes":["n2203921041","n185967054","n185967063","n185967065","n185967068","n185967070","n185967074","n185967075","n185967076","n185967077"]},"w209718306":{"id":"w209718306","tags":{"area":"yes","building":"yes"},"nodes":["n2199127091","n2199127092","n2199127093","n2199127094","n2199127091"]},"w209718307":{"id":"w209718307","tags":{"area":"yes","building":"yes"},"nodes":["n2199127095","n2199127096","n2199127097","n2199127098","n2199127095"]},"w209718305":{"id":"w209718305","tags":{"area":"yes","building":"yes"},"nodes":["n2199127075","n2199127076","n2199127077","n2199127078","n2199127079","n2199127080","n2199127081","n2199127082","n2199127083","n2199127084","n2199127085","n2199127086","n2199127087","n2199127088","n2199127089","n2199127090","n2199127075"]},"n185960199":{"id":"n185960199","loc":[-85.62965,41.95469]},"n185980737":{"id":"n185980737","loc":[-85.629083,41.953725]},"n2114807561":{"id":"n2114807561","loc":[-85.6297681,41.9524688]},"n2114807597":{"id":"n2114807597","loc":[-85.6296517,41.952563]},"n185960197":{"id":"n185960197","loc":[-85.629676,41.9537314]},"n185978791":{"id":"n185978791","loc":[-85.6244542,41.9547066]},"w17967573":{"id":"w17967573","tags":{"highway":"residential","name":"E Wheeler St"},"nodes":["n185960195","n2114807561","n185968102","n185967430","n185986157","n185978392"]},"w17966553":{"id":"w17966553","tags":{"highway":"residential","name":"East Hoffman Street"},"nodes":["n185971631","n185978784","n185967432","n185968106","n185960199","n185978787","n185978790","n185978791"]},"w17966787":{"id":"w17966787","tags":{"highway":"residential","name":"East Cushman Street"},"nodes":["n185980735","n185980737","n185960197","n185968104","n185960792"]},"w17964723":{"id":"w17964723","tags":{"highway":"residential","name":"Cushman Street"},"nodes":["n185960792","n185960794","n185960796"]},"w17964654":{"id":"w17964654","tags":{"highway":"residential","name":"Pine Street"},"nodes":["n185960195","n2114807597","n185960197","n185960199"]},"n1819848862":{"id":"n1819848862","loc":[-85.6346087,41.9545845]},"n1819848935":{"id":"n1819848935","loc":[-85.6345948,41.9537717]},"n1819848973":{"id":"n1819848973","loc":[-85.6334247,41.9537827]},"n1819848997":{"id":"n1819848997","loc":[-85.6334386,41.9545956]},"n2189015861":{"id":"n2189015861","loc":[-85.6375906,41.954836]},"n2189015865":{"id":"n2189015865","loc":[-85.6383307,41.9548291]},"n2189015867":{"id":"n2189015867","loc":[-85.6383337,41.9550072]},"n2189015868":{"id":"n2189015868","loc":[-85.6380986,41.9550094]},"n2189015869":{"id":"n2189015869","loc":[-85.6381005,41.9551226]},"n2199109808":{"id":"n2199109808","loc":[-85.6372702,41.9522894]},"n2199109810":{"id":"n2199109810","loc":[-85.6372677,41.9521583]},"n2199109812":{"id":"n2199109812","loc":[-85.6369505,41.9521617]},"n2199109814":{"id":"n2199109814","loc":[-85.636953,41.9522927]},"n185952156":{"id":"n185952156","loc":[-85.640983,41.9546557]},"n185953423":{"id":"n185953423","loc":[-85.641871,41.954652]},"n185971637":{"id":"n185971637","loc":[-85.641583,41.95465]},"n185971639":{"id":"n185971639","loc":[-85.6421344,41.9546444]},"n185971642":{"id":"n185971642","loc":[-85.6428264,41.9545612]},"n185971648":{"id":"n185971648","loc":[-85.6436023,41.9544262]},"n185975066":{"id":"n185975066","loc":[-85.640532,41.953638]},"n185975067":{"id":"n185975067","loc":[-85.64079,41.953638]},"n185982166":{"id":"n185982166","loc":[-85.6399012,41.9523817]},"n2189015858":{"id":"n2189015858","loc":[-85.6376104,41.9560138]},"n2189015870":{"id":"n2189015870","loc":[-85.6386794,41.9551172]},"n2189015871":{"id":"n2189015871","loc":[-85.6386817,41.955256]},"n2189015873":{"id":"n2189015873","loc":[-85.6385437,41.9552573]},"n2189015876":{"id":"n2189015876","loc":[-85.638555,41.9559278]},"n2189015879":{"id":"n2189015879","loc":[-85.6384954,41.9559283]},"n2189015882":{"id":"n2189015882","loc":[-85.6384965,41.9559935]},"n2189015885":{"id":"n2189015885","loc":[-85.6383533,41.9559949]},"n2189015888":{"id":"n2189015888","loc":[-85.638351,41.9558607]},"n2189015891":{"id":"n2189015891","loc":[-85.6382178,41.9558619]},"n2189015894":{"id":"n2189015894","loc":[-85.6382203,41.956008]},"w208627223":{"id":"w208627223","tags":{"area":"yes","building":"yes"},"nodes":["n2189015858","n2189015861","n2189015865","n2189015867","n2189015868","n2189015869","n2189015870","n2189015871","n2189015873","n2189015876","n2189015879","n2189015882","n2189015885","n2189015888","n2189015891","n2189015894","n2189015858"]},"w170848328":{"id":"w170848328","tags":{"leisure":"park","name":"Bowman Park"},"nodes":["n1819848935","n1819848973","n1819848997","n1819848862","n1819848935"]},"w17965866":{"id":"w17965866","tags":{"highway":"residential","name":"West Hoffman Street"},"nodes":["n185971631","n185971632","n185964359","n185965025","n1475293264","n185952156","n185971637","n185953423","n185971639","n185971642","n185971648"]},"w209717051":{"id":"w209717051","tags":{"amenity":"place_of_worship","area":"yes","building":"yes","denomination":"baptist","name":"Calvary Missionary Baptist Church","religion":"christian"},"nodes":["n2199109808","n2199109810","n2199109812","n2199109814","n2199109808"]},"w17966172":{"id":"w17966172","tags":{"highway":"residential","name":"West Cushman Street"},"nodes":["n185960796","n185975064","n185964358","n185965023","n1475293222","n185975066","n185975067"]},"w17966975":{"id":"w17966975","tags":{"highway":"residential","name":"W Wheeler St"},"nodes":["n185978392","n185982163","n185964357","n185965021","n1475293261","n185982166"]},"n185960684":{"id":"n185960684","loc":[-85.622687,41.951885]},"n185960686":{"id":"n185960686","loc":[-85.622492,41.951901]},"n185978795":{"id":"n185978795","loc":[-85.6240991,41.954708]},"n185978803":{"id":"n185978803","loc":[-85.623348,41.954547]},"n185978806":{"id":"n185978806","loc":[-85.623123,41.954502]},"n185978808":{"id":"n185978808","loc":[-85.622923,41.954469]},"n185978810":{"id":"n185978810","loc":[-85.622787,41.954457]},"n185978811":{"id":"n185978811","loc":[-85.622612,41.954458]},"n185978813":{"id":"n185978813","loc":[-85.622368,41.954472]},"n1819790545":{"id":"n1819790545","loc":[-85.6240295,41.9548949]},"n1819790621":{"id":"n1819790621","loc":[-85.6235789,41.954855]},"n1819790664":{"id":"n1819790664","loc":[-85.6238363,41.9549507]},"n1819790683":{"id":"n1819790683","loc":[-85.6224727,41.9545921]},"n1819790730":{"id":"n1819790730","loc":[-85.6227527,41.9545795]},"n1819790740":{"id":"n1819790740","loc":[-85.6240402,41.9550784]},"n1819790831":{"id":"n1819790831","loc":[-85.624126,41.9549986]},"n1819790861":{"id":"n1819790861","loc":[-85.6231712,41.9546872]},"n1819790887":{"id":"n1819790887","loc":[-85.6242762,41.955206]},"n2168544739":{"id":"n2168544739","loc":[-85.6249102,41.952801]},"n2168544740":{"id":"n2168544740","loc":[-85.6251859,41.9527564]},"n2168544741":{"id":"n2168544741","loc":[-85.6255515,41.9527921]},"n2168544742":{"id":"n2168544742","loc":[-85.626001,41.9529481]},"n2168544743":{"id":"n2168544743","loc":[-85.6265284,41.9529838]},"n2168544744":{"id":"n2168544744","loc":[-85.626942,41.9528857]},"n2168544745":{"id":"n2168544745","loc":[-85.6270918,41.9526851]},"n2168544746":{"id":"n2168544746","loc":[-85.6272117,41.95244]},"n2168544747":{"id":"n2168544747","loc":[-85.6271578,41.952226]},"n2168544748":{"id":"n2168544748","loc":[-85.6270019,41.9519719]},"n2168544749":{"id":"n2168544749","loc":[-85.6268221,41.9518382]},"n2168544750":{"id":"n2168544750","loc":[-85.6265284,41.951807]},"n2168544751":{"id":"n2168544751","loc":[-85.6256534,41.9518516]},"n2168544752":{"id":"n2168544752","loc":[-85.6253477,41.9518338]},"n2168544753":{"id":"n2168544753","loc":[-85.6251139,41.9517669]},"n185955747":{"id":"n185955747","loc":[-85.620674,41.954709]},"n185960688":{"id":"n185960688","loc":[-85.621032,41.951913]},"n185972054":{"id":"n185972054","loc":[-85.6186728,41.9547335]},"n185978814":{"id":"n185978814","loc":[-85.6201708,41.9547403]},"n1819790532":{"id":"n1819790532","loc":[-85.6244908,41.9555731]},"n1819790536":{"id":"n1819790536","loc":[-85.6217925,41.9583135]},"n1819790538":{"id":"n1819790538","loc":[-85.6233954,41.9600014]},"n1819790539":{"id":"n1819790539","loc":[-85.6204611,41.9562117]},"n1819790546":{"id":"n1819790546","loc":[-85.6210898,41.9567657]},"n1819790548":{"id":"n1819790548","loc":[-85.6202465,41.9562237]},"n1819790550":{"id":"n1819790550","loc":[-85.6250165,41.9560677]},"n1819790551":{"id":"n1819790551","loc":[-85.6227946,41.9597023]},"n1819790553":{"id":"n1819790553","loc":[-85.6215726,41.9584571]},"n1819790556":{"id":"n1819790556","loc":[-85.6196306,41.9573002]},"n1819790557":{"id":"n1819790557","loc":[-85.6209503,41.9563109]},"n1819790558":{"id":"n1819790558","loc":[-85.6196939,41.9574085]},"n1819790561":{"id":"n1819790561","loc":[-85.621079,41.957751]},"n1819790562":{"id":"n1819790562","loc":[-85.6224255,41.9611417]},"n1819790565":{"id":"n1819790565","loc":[-85.6232506,41.9604841]},"n1819790566":{"id":"n1819790566","loc":[-85.6190835,41.9562909]},"n1819790567":{"id":"n1819790567","loc":[-85.622227,41.9593028]},"n1819790569":{"id":"n1819790569","loc":[-85.620976,41.9591039]},"n1819790571":{"id":"n1819790571","loc":[-85.6212078,41.9565303]},"n1819790572":{"id":"n1819790572","loc":[-85.6235306,41.9595102]},"n1819790581":{"id":"n1819790581","loc":[-85.6235563,41.9579351]},"n1819790584":{"id":"n1819790584","loc":[-85.6230371,41.9574598]},"n1819790586":{"id":"n1819790586","loc":[-85.6211748,41.9564272]},"n1819790588":{"id":"n1819790588","loc":[-85.6226508,41.9601086]},"n1819790591":{"id":"n1819790591","loc":[-85.6218032,41.9607468]},"n1819790593":{"id":"n1819790593","loc":[-85.6207915,41.9618735]},"n1819790596":{"id":"n1819790596","loc":[-85.6252955,41.9567858]},"n1819790598":{"id":"n1819790598","loc":[-85.6196618,41.9568939]},"n1819790600":{"id":"n1819790600","loc":[-85.6224416,41.9587084]},"n1819790602":{"id":"n1819790602","loc":[-85.6217442,41.9558641]},"n1819790603":{"id":"n1819790603","loc":[-85.6213355,41.9592116]},"n1819790604":{"id":"n1819790604","loc":[-85.622801,41.9573042]},"n1819790608":{"id":"n1819790608","loc":[-85.6199729,41.9574325]},"n1819790610":{"id":"n1819790610","loc":[-85.6195555,41.9557165]},"n1819790611":{"id":"n1819790611","loc":[-85.622978,41.9586007]},"n1819790613":{"id":"n1819790613","loc":[-85.6253963,41.9562636]},"n1819790614":{"id":"n1819790614","loc":[-85.6235252,41.9580342]},"n1819790616":{"id":"n1819790616","loc":[-85.6232988,41.9596305]},"n1819790617":{"id":"n1819790617","loc":[-85.6226776,41.9598732]},"n1819790619":{"id":"n1819790619","loc":[-85.625553,41.9561794]},"n1819790620":{"id":"n1819790620","loc":[-85.6235574,41.959231]},"n1819790624":{"id":"n1819790624","loc":[-85.6228429,41.9573726]},"n1819790626":{"id":"n1819790626","loc":[-85.6193785,41.9556766]},"n1819790628":{"id":"n1819790628","loc":[-85.620092,41.9554253]},"n1819790630":{"id":"n1819790630","loc":[-85.6226658,41.9604402]},"n1819790638":{"id":"n1819790638","loc":[-85.6219964,41.9602561]},"n1819790640":{"id":"n1819790640","loc":[-85.6232731,41.9599969]},"n1819790643":{"id":"n1819790643","loc":[-85.6247698,41.9568895]},"n1819790650":{"id":"n1819790650","loc":[-85.6216412,41.9550149]},"n1819790652":{"id":"n1819790652","loc":[-85.6224952,41.9603918]},"n1819790656":{"id":"n1819790656","loc":[-85.61918,41.9555649]},"n1819790661":{"id":"n1819790661","loc":[-85.6200169,41.955505]},"n1819790662":{"id":"n1819790662","loc":[-85.6217389,41.9563149]},"n1819790666":{"id":"n1819790666","loc":[-85.6229566,41.9598373]},"n1819790667":{"id":"n1819790667","loc":[-85.6209117,41.9609189]},"n1819790669":{"id":"n1819790669","loc":[-85.6252311,41.9562353]},"n1819790670":{"id":"n1819790670","loc":[-85.6209758,41.961868]},"n1819790672":{"id":"n1819790672","loc":[-85.6209557,41.9589078]},"n1819790673":{"id":"n1819790673","loc":[-85.6190352,41.9561393]},"n1819790675":{"id":"n1819790675","loc":[-85.6236432,41.9586685]},"n1819790676":{"id":"n1819790676","loc":[-85.6194901,41.9565389]},"n1819790678":{"id":"n1819790678","loc":[-85.6219266,41.9582417]},"n1819790680":{"id":"n1819790680","loc":[-85.6208258,41.9557211]},"n1819790681":{"id":"n1819790681","loc":[-85.6212024,41.9613212]},"n1819790682":{"id":"n1819790682","loc":[-85.624877,41.9559401]},"n1819790684":{"id":"n1819790684","loc":[-85.6206499,41.9583693]},"n1819790699":{"id":"n1819790699","loc":[-85.6215243,41.956279]},"n1819790701":{"id":"n1819790701","loc":[-85.6246625,41.9559321]},"n1819790703":{"id":"n1819790703","loc":[-85.6230478,41.9585089]},"n1819790708":{"id":"n1819790708","loc":[-85.6211102,41.9575402]},"n1819790710":{"id":"n1819790710","loc":[-85.6215082,41.9548468]},"n1819790711":{"id":"n1819790711","loc":[-85.6206552,41.9586007]},"n1819790713":{"id":"n1819790713","loc":[-85.6215404,41.9549705]},"n1819790715":{"id":"n1819790715","loc":[-85.6216906,41.955521]},"n1819790717":{"id":"n1819790717","loc":[-85.6215404,41.9547391]},"n1819790722":{"id":"n1819790722","loc":[-85.6219964,41.9599131]},"n1819790723":{"id":"n1819790723","loc":[-85.622286,41.9606989]},"n1819790725":{"id":"n1819790725","loc":[-85.6228439,41.9572005]},"n1819790727":{"id":"n1819790727","loc":[-85.6202518,41.9554458]},"n1819790728":{"id":"n1819790728","loc":[-85.623434,41.9575276]},"n1819790729":{"id":"n1819790729","loc":[-85.6234287,41.9568576]},"n1819790732":{"id":"n1819790732","loc":[-85.6229566,41.9571369]},"n1819790733":{"id":"n1819790733","loc":[-85.6225543,41.9590275]},"n1819790734":{"id":"n1819790734","loc":[-85.6232892,41.9583135]},"n1819790736":{"id":"n1819790736","loc":[-85.622977,41.9608551]},"n1819790737":{"id":"n1819790737","loc":[-85.624008,41.9569533]},"n1819790741":{"id":"n1819790741","loc":[-85.6212775,41.9608545]},"n1819790742":{"id":"n1819790742","loc":[-85.6231282,41.9569932]},"n1819790743":{"id":"n1819790743","loc":[-85.6224523,41.9591831]},"n1819790744":{"id":"n1819790744","loc":[-85.6210951,41.9610819]},"n1819790745":{"id":"n1819790745","loc":[-85.6220114,41.960544]},"n1819790755":{"id":"n1819790755","loc":[-85.6216369,41.9553854]},"n1819790757":{"id":"n1819790757","loc":[-85.6209986,41.9592709]},"n1819790758":{"id":"n1819790758","loc":[-85.6200437,41.9563468]},"n1819790764":{"id":"n1819790764","loc":[-85.6219363,41.9596823]},"n1819790765":{"id":"n1819790765","loc":[-85.6237612,41.9568496]},"n1819790769":{"id":"n1819790769","loc":[-85.6212389,41.9593433]},"n1819790771":{"id":"n1819790771","loc":[-85.6210726,41.9560123]},"n1819790772":{"id":"n1819790772","loc":[-85.6212711,41.9561838]},"n1819790776":{"id":"n1819790776","loc":[-85.6234437,41.9577795]},"n1819790777":{"id":"n1819790777","loc":[-85.6212502,41.9618599]},"n1819790783":{"id":"n1819790783","loc":[-85.6216895,41.9610585]},"n1819790784":{"id":"n1819790784","loc":[-85.6200115,41.9556367]},"n1819790785":{"id":"n1819790785","loc":[-85.6210576,41.9573002]},"n1819790786":{"id":"n1819790786","loc":[-85.621138,41.9576632]},"n1819790788":{"id":"n1819790788","loc":[-85.6207733,41.9578946]},"n1819790789":{"id":"n1819790789","loc":[-85.6200705,41.9571566]},"n1819790790":{"id":"n1819790790","loc":[-85.6245337,41.9558443]},"n1819790792":{"id":"n1819790792","loc":[-85.621932,41.9608066]},"n1819790793":{"id":"n1819790793","loc":[-85.6233578,41.9581385]},"n1819790794":{"id":"n1819790794","loc":[-85.6204557,41.9555136]},"n1819790797":{"id":"n1819790797","loc":[-85.6235038,41.9576074]},"n1819790800":{"id":"n1819790800","loc":[-85.6214438,41.9607508]},"n1819790801":{"id":"n1819790801","loc":[-85.623492,41.9602129]},"n1819790802":{"id":"n1819790802","loc":[-85.6216691,41.9546553]},"n1819790803":{"id":"n1819790803","loc":[-85.6231057,41.9586851]},"n1819790804":{"id":"n1819790804","loc":[-85.6209224,41.9578673]},"n1819790813":{"id":"n1819790813","loc":[-85.620092,41.9572962]},"n1819790814":{"id":"n1819790814","loc":[-85.6216691,41.9552218]},"n1819790816":{"id":"n1819790816","loc":[-85.6216144,41.9609668]},"n1819790818":{"id":"n1819790818","loc":[-85.6216906,41.9557324]},"n1819790820":{"id":"n1819790820","loc":[-85.6192069,41.9564186]},"n1819790823":{"id":"n1819790823","loc":[-85.6211155,41.9566027]},"n1819790825":{"id":"n1819790825","loc":[-85.6233106,41.9569294]},"n1819790839":{"id":"n1819790839","loc":[-85.625671,41.9564986]},"n1819790842":{"id":"n1819790842","loc":[-85.6235252,41.9567379]},"n1819790844":{"id":"n1819790844","loc":[-85.6253813,41.9566342]},"n1819790847":{"id":"n1819790847","loc":[-85.6200963,41.9567702]},"n1819790849":{"id":"n1819790849","loc":[-85.6238031,41.9587449]},"n1819790851":{"id":"n1819790851","loc":[-85.6234984,41.9584571]},"n1819790856":{"id":"n1819790856","loc":[-85.6242226,41.9570092]},"n1819790865":{"id":"n1819790865","loc":[-85.6200265,41.9569458]},"n1819790869":{"id":"n1819790869","loc":[-85.6230049,41.9601245]},"n1819790871":{"id":"n1819790871","loc":[-85.6190727,41.9558322]},"n1819790873":{"id":"n1819790873","loc":[-85.6217442,41.9550104]},"n1819790875":{"id":"n1819790875","loc":[-85.6208044,41.9587808]},"n1819790879":{"id":"n1819790879","loc":[-85.6198444,41.9574484]},"n1819790883":{"id":"n1819790883","loc":[-85.623713,41.9588719]},"n1819790885":{"id":"n1819790885","loc":[-85.6223289,41.9605075]},"n1819790889":{"id":"n1819790889","loc":[-85.6208044,41.9562437]},"n1819790893":{"id":"n1819790893","loc":[-85.6218183,41.9559684]},"n1819790906":{"id":"n1819790906","loc":[-85.6214052,41.958697]},"n1819790913":{"id":"n1819790913","loc":[-85.6209981,41.9609957]},"n1819790917":{"id":"n1819790917","loc":[-85.6216208,41.9604436]},"n1819790919":{"id":"n1819790919","loc":[-85.6209406,41.9616373]},"n1819790920":{"id":"n1819790920","loc":[-85.6221948,41.9583334]},"n1819790922":{"id":"n1819790922","loc":[-85.6216681,41.9615292]},"n1819790924":{"id":"n1819790924","loc":[-85.6210147,41.9570489]},"n1819790929":{"id":"n1819790929","loc":[-85.6193678,41.955521]},"w17964707":{"id":"w17964707","tags":{"highway":"residential","name":"11th Ave"},"nodes":["n185960682","n185960684","n185960686","n185960688","n185960690"]},"w201484345":{"id":"w201484345","tags":{"bridge":"yes","highway":"residential","name":"E Hoffman St"},"nodes":["n185978791","n185978795"]},"w201484348":{"id":"w201484348","tags":{"highway":"residential","name":"E Hoffman St"},"nodes":["n185978795","n185978800","n185978803","n185978806","n185978808","n185978810","n185978811","n185978813","n185955747","n185978814","n185972054","n185978817"]},"w170843845":{"id":"w170843845","tags":{"landuse":"reservoir","name":"Hoffman Pond","natural":"water"},"nodes":["n1819790732","n1819790742","n1819790825","n1819790729","n1819790842","n1819790765","n1819790737","n1819790856","n1819790643","n1819790596","n1819790844","n1819790839","n1819849190","n1819790619","n1819790613","n1819790669","n1819790550","n1819790682","n1819790701","n1819790790","n1819790532","n1819790887","n1819790740","n1819790831","n1819790545","n1819790664","n1819790621","n1819790861","n1819790730","n1819790683","n1819790802","n1819790717","n1819790710","n1819790713","n1819790650","n1819790873","n1819790814","n1819790755","n1819790715","n1819790818","n1819790602","n1819790893","n1819790662","n1819790699","n1819790772","n1819790771","n1819790680","n1819790794","n1819790727","n1819790628","n1819790661","n1819790784","n1819790610","n1819790626","n1819790929","n1819790656","n1819790871","n1819790673","n1819790566","n1819790820","n1819790676","n1819790598","n1819790556","n1819790558","n1819790879","n1819790608","n1819790813","n1819790789","n1819790865","n1819790847","n1819790758","n1819790548","n1819790539","n1819790889","n1819790557","n1819790586","n1819790571","n1819790823","n1819790546","n1819790924","n1819790785","n1819790708","n1819790786","n1819790561","n1819790804","n1819790788","n1819790684","n1819790711","n1819790875","n1819790672","n1819790569","n1819790757","n1819790769","n1819790603","n1819790906","n1819790553","n1819790536","n1819790678","n1819790920","n1819790600","n1819790733","n1819790743","n1819790567","n1819790764","n1819790722","n1819790638","n1819790917","n1819790800","n1819790741","n1819790667","n1819790913","n1819790744","n1819790816","n1819790591","n1819790745","n1819790885","n1819790652","n1819790588","n1819790617","n1819790551","n1819790666","n1819790869","n1819790630","n1819790723","n1819790792","n1819790783","n1819790681","n1819790919","n1819790593","n1819790670","n1819790777","n1819790922","n1819790562","n1819790736","n1819790565","n1819790801","n1819790538","n1819790640","n1819790616","n1819790572","n1819790620","n1819790883","n1819790849","n1819790675","n1819790851","n1819790803","n1819790611","n1819790703","n1819790734","n1819790793","n1819790614","n1819790581","n1819790776","n1819790797","n1819790728","n1819790584","n1819790624","n1819790604","n1819790725","n1819790732"]},"w206805240":{"id":"w206805240","tags":{"waterway":"river"},"nodes":["n2168544738","n2168544739","n2168544740","n2168544741","n2168544742","n2168544743","n2168544744","n2168544745","n2168544746","n2168544747","n2168544748","n2168544749","n2168544750","n2168544751","n2168544752","n2168544753","n1819848944"]},"n394490429":{"id":"n394490429","loc":[-85.643883,41.954365]},"n185953421":{"id":"n185953421","loc":[-85.641876,41.954946]},"n185953417":{"id":"n185953417","loc":[-85.6418306,41.9551597]},"n185977233":{"id":"n185977233","loc":[-85.642987,41.95486]},"n185977232":{"id":"n185977232","loc":[-85.642894,41.9547842]},"n1475293244":{"id":"n1475293244","loc":[-85.63974,41.9521543]},"n1819848890":{"id":"n1819848890","loc":[-85.6410004,41.9552822]},"n1819848965":{"id":"n1819848965","loc":[-85.6409795,41.9553892]},"n2189015846":{"id":"n2189015846","loc":[-85.6420457,41.9549528]},"n2189015849":{"id":"n2189015849","loc":[-85.6425867,41.9551392]},"n2189015852":{"id":"n2189015852","loc":[-85.6426877,41.9549771]},"n2199109816":{"id":"n2199109816","loc":[-85.6399215,41.9540925]},"n2199109818":{"id":"n2199109818","loc":[-85.6399182,41.9538236]},"n2199109820":{"id":"n2199109820","loc":[-85.6402201,41.9538216]},"n2199109822":{"id":"n2199109822","loc":[-85.640222,41.9539771]},"n2199109825":{"id":"n2199109825","loc":[-85.6402904,41.9539766]},"n2199109827":{"id":"n2199109827","loc":[-85.6402918,41.95409]},"n2199109829":{"id":"n2199109829","loc":[-85.6395845,41.9544626]},"n2199109831":{"id":"n2199109831","loc":[-85.6395792,41.9540671]},"n2199109833":{"id":"n2199109833","loc":[-85.6397173,41.9540661]},"n2199109835":{"id":"n2199109835","loc":[-85.6397226,41.9544616]},"n2199109837":{"id":"n2199109837","loc":[-85.6399641,41.9545058]},"n2199109839":{"id":"n2199109839","loc":[-85.6399637,41.9541859]},"n2199109841":{"id":"n2199109841","loc":[-85.6401098,41.9541858]},"n2199109843":{"id":"n2199109843","loc":[-85.64011,41.9543272]},"n2199109845":{"id":"n2199109845","loc":[-85.6400783,41.9543273]},"n2199109847":{"id":"n2199109847","loc":[-85.6400785,41.9545058]},"n2199109853":{"id":"n2199109853","loc":[-85.6396184,41.9554049]},"n2199109855":{"id":"n2199109855","loc":[-85.6396825,41.9553713]},"n185949745":{"id":"n185949745","loc":[-85.6442727,41.9553112]},"n185949748":{"id":"n185949748","loc":[-85.6448804,41.9555238]},"n185949755":{"id":"n185949755","loc":[-85.6420011,41.9603536]},"n185949763":{"id":"n185949763","loc":[-85.6408843,41.9555822]},"n185949765":{"id":"n185949765","loc":[-85.6414548,41.9557751]},"n185952158":{"id":"n185952158","loc":[-85.640066,41.956854]},"n185952160":{"id":"n185952160","loc":[-85.639848,41.957229]},"n185952161":{"id":"n185952161","loc":[-85.6396089,41.9576192]},"n185952163":{"id":"n185952163","loc":[-85.63892,41.957957]},"n185953413":{"id":"n185953413","loc":[-85.64162,41.955475]},"n185971651":{"id":"n185971651","loc":[-85.6440766,41.9543462]},"n185977234":{"id":"n185977234","loc":[-85.645044,41.955581]},"n394490395":{"id":"n394490395","loc":[-85.657336,41.936762]},"n394490396":{"id":"n394490396","loc":[-85.653896,41.936978]},"n394490397":{"id":"n394490397","loc":[-85.653732,41.937386]},"n394490398":{"id":"n394490398","loc":[-85.65182,41.937378]},"n394490399":{"id":"n394490399","loc":[-85.651843,41.938445]},"n394490400":{"id":"n394490400","loc":[-85.652536,41.938447]},"n394490401":{"id":"n394490401","loc":[-85.652533,41.938901]},"n394490402":{"id":"n394490402","loc":[-85.652084,41.9389]},"n394490403":{"id":"n394490403","loc":[-85.6521,41.939627]},"n394490404":{"id":"n394490404","loc":[-85.652301,41.939628]},"n394490405":{"id":"n394490405","loc":[-85.652302,41.939755]},"n394490406":{"id":"n394490406","loc":[-85.652783,41.939747]},"n394490407":{"id":"n394490407","loc":[-85.652835,41.94112]},"n394490408":{"id":"n394490408","loc":[-85.651968,41.941123]},"n394490409":{"id":"n394490409","loc":[-85.651983,41.941969]},"n394490410":{"id":"n394490410","loc":[-85.652908,41.941961]},"n394490411":{"id":"n394490411","loc":[-85.65292,41.94278]},"n394490412":{"id":"n394490412","loc":[-85.651698,41.942816]},"n394490413":{"id":"n394490413","loc":[-85.651509,41.942823]},"n394490414":{"id":"n394490414","loc":[-85.651272,41.942837]},"n394490415":{"id":"n394490415","loc":[-85.651272,41.943325]},"n394490416":{"id":"n394490416","loc":[-85.65122,41.944053]},"n394490417":{"id":"n394490417","loc":[-85.651193,41.944449]},"n394490418":{"id":"n394490418","loc":[-85.651088,41.944969]},"n394490419":{"id":"n394490419","loc":[-85.650949,41.945554]},"n394490420":{"id":"n394490420","loc":[-85.650907,41.945719]},"n394490421":{"id":"n394490421","loc":[-85.650808,41.946016]},"n394490422":{"id":"n394490422","loc":[-85.650712,41.946516]},"n394490423":{"id":"n394490423","loc":[-85.650493,41.947166]},"n394490424":{"id":"n394490424","loc":[-85.650626,41.947213]},"n394490425":{"id":"n394490425","loc":[-85.650201,41.948109]},"n394490426":{"id":"n394490426","loc":[-85.649868,41.948797]},"n394490427":{"id":"n394490427","loc":[-85.649669,41.949161]},"n394490428":{"id":"n394490428","loc":[-85.64659,41.954067]},"n394490430":{"id":"n394490430","loc":[-85.644034,41.95444]},"n394490431":{"id":"n394490431","loc":[-85.644248,41.954507]},"n394490432":{"id":"n394490432","loc":[-85.64491,41.954481]},"n394490433":{"id":"n394490433","loc":[-85.645213,41.954433]},"n394490434":{"id":"n394490434","loc":[-85.645426,41.954477]},"n394490435":{"id":"n394490435","loc":[-85.6458,41.954704]},"n394490436":{"id":"n394490436","loc":[-85.64605,41.954804]},"n394490437":{"id":"n394490437","loc":[-85.646125,41.954817]},"n394490438":{"id":"n394490438","loc":[-85.646002,41.954997]},"n394490439":{"id":"n394490439","loc":[-85.645764,41.955366]},"n394490440":{"id":"n394490440","loc":[-85.645525,41.955734]},"n394490441":{"id":"n394490441","loc":[-85.64443,41.957424]},"n394490442":{"id":"n394490442","loc":[-85.641712,41.961723]},"n394490443":{"id":"n394490443","loc":[-85.640747,41.963246]},"n394490444":{"id":"n394490444","loc":[-85.637803,41.967894]},"n394490445":{"id":"n394490445","loc":[-85.637673,41.967861]},"n394490446":{"id":"n394490446","loc":[-85.636637,41.969275]},"n394490447":{"id":"n394490447","loc":[-85.634923,41.969269]},"n394490448":{"id":"n394490448","loc":[-85.634893,41.968537]},"n394490449":{"id":"n394490449","loc":[-85.634544,41.96927]},"n394490450":{"id":"n394490450","loc":[-85.630835,41.969274]},"n394490451":{"id":"n394490451","loc":[-85.630834,41.968348]},"n394490452":{"id":"n394490452","loc":[-85.630857,41.968179]},"n394490453":{"id":"n394490453","loc":[-85.630924,41.968044]},"n394490454":{"id":"n394490454","loc":[-85.631004,41.967925]},"n394490455":{"id":"n394490455","loc":[-85.631143,41.967811]},"n394490456":{"id":"n394490456","loc":[-85.631311,41.967736]},"n394490457":{"id":"n394490457","loc":[-85.631595,41.967693]},"n394490458":{"id":"n394490458","loc":[-85.63325,41.967702]},"n394490459":{"id":"n394490459","loc":[-85.633247,41.967021]},"n394490460":{"id":"n394490460","loc":[-85.634858,41.967021]},"n394490461":{"id":"n394490461","loc":[-85.634865,41.967711]},"n394490462":{"id":"n394490462","loc":[-85.634884,41.968231]},"n394490463":{"id":"n394490463","loc":[-85.636559,41.963867]},"n394490464":{"id":"n394490464","loc":[-85.634832,41.963866]},"n394490465":{"id":"n394490465","loc":[-85.63481,41.961899]},"n394490466":{"id":"n394490466","loc":[-85.637219,41.961842]},"n394490467":{"id":"n394490467","loc":[-85.637837,41.960019]},"n394490468":{"id":"n394490468","loc":[-85.637459,41.960022]},"n394490469":{"id":"n394490469","loc":[-85.635295,41.959987]},"n394490470":{"id":"n394490470","loc":[-85.634783,41.959979]},"n394490471":{"id":"n394490471","loc":[-85.634776,41.959834]},"n394490472":{"id":"n394490472","loc":[-85.634767,41.959009]},"n394490473":{"id":"n394490473","loc":[-85.634763,41.958292]},"n394490474":{"id":"n394490474","loc":[-85.633346,41.958287]},"n394490475":{"id":"n394490475","loc":[-85.632128,41.9583]},"n394490476":{"id":"n394490476","loc":[-85.631414,41.958318]},"n394490477":{"id":"n394490477","loc":[-85.63137,41.959033]},"n394490478":{"id":"n394490478","loc":[-85.631325,41.959753]},"n394490479":{"id":"n394490479","loc":[-85.631494,41.95977]},"n394490480":{"id":"n394490480","loc":[-85.631456,41.960673]},"n394490481":{"id":"n394490481","loc":[-85.631421,41.961494]},"n394490482":{"id":"n394490482","loc":[-85.631404,41.961887]},"n394490483":{"id":"n394490483","loc":[-85.631401,41.961968]},"n394490484":{"id":"n394490484","loc":[-85.630962,41.961967]},"n394490485":{"id":"n394490485","loc":[-85.6299,41.961973]},"n394490486":{"id":"n394490486","loc":[-85.624929,41.962002]},"n394490487":{"id":"n394490487","loc":[-85.623333,41.961987]},"n394490488":{"id":"n394490488","loc":[-85.621894,41.963956]},"n394490489":{"id":"n394490489","loc":[-85.62131,41.963727]},"n394490490":{"id":"n394490490","loc":[-85.621216,41.963868]},"n394490491":{"id":"n394490491","loc":[-85.620356,41.965119]},"n394490492":{"id":"n394490492","loc":[-85.620848,41.965341]},"n394490493":{"id":"n394490493","loc":[-85.620684,41.965558]},"n394490494":{"id":"n394490494","loc":[-85.620621,41.965658]},"n394490495":{"id":"n394490495","loc":[-85.618165,41.965759]},"n394490496":{"id":"n394490496","loc":[-85.618071,41.965759]},"n394490497":{"id":"n394490497","loc":[-85.617986,41.965759]},"n394490498":{"id":"n394490498","loc":[-85.605673,41.965764]},"n394490499":{"id":"n394490499","loc":[-85.605668,41.963548]},"n394490500":{"id":"n394490500","loc":[-85.605664,41.962094]},"n394490501":{"id":"n394490501","loc":[-85.595828,41.962159]},"n394490502":{"id":"n394490502","loc":[-85.587869,41.962169]},"n394490503":{"id":"n394490503","loc":[-85.586289,41.962179]},"n394490504":{"id":"n394490504","loc":[-85.583774,41.962178]},"n394490505":{"id":"n394490505","loc":[-85.583774,41.961789]},"n394490506":{"id":"n394490506","loc":[-85.581303,41.961783]},"n394490507":{"id":"n394490507","loc":[-85.581304,41.961616]},"n394490508":{"id":"n394490508","loc":[-85.581292,41.961616]},"n394490509":{"id":"n394490509","loc":[-85.581247,41.959244]},"n394490510":{"id":"n394490510","loc":[-85.581245,41.958394]},"n394490511":{"id":"n394490511","loc":[-85.581276,41.958372]},"n394490512":{"id":"n394490512","loc":[-85.581302,41.958353]},"n394490513":{"id":"n394490513","loc":[-85.581376,41.9583]},"n394490514":{"id":"n394490514","loc":[-85.582256,41.957663]},"n394490515":{"id":"n394490515","loc":[-85.585299,41.955483]},"n394490516":{"id":"n394490516","loc":[-85.585588,41.955331]},"n394490517":{"id":"n394490517","loc":[-85.586053,41.955163]},"n394490518":{"id":"n394490518","loc":[-85.58632,41.955076]},"n394490519":{"id":"n394490519","loc":[-85.586478,41.955025]},"n394490520":{"id":"n394490520","loc":[-85.58692,41.954947]},"n394490521":{"id":"n394490521","loc":[-85.587327,41.954914]},"n394490522":{"id":"n394490522","loc":[-85.587345,41.954913]},"n394490523":{"id":"n394490523","loc":[-85.587358,41.954913]},"n394490524":{"id":"n394490524","loc":[-85.58963,41.954877]},"n394490525":{"id":"n394490525","loc":[-85.591077,41.954865]},"n394490526":{"id":"n394490526","loc":[-85.594824,41.954843]},"n394490527":{"id":"n394490527","loc":[-85.594804,41.95331]},"n394490528":{"id":"n394490528","loc":[-85.599336,41.95331]},"n394490529":{"id":"n394490529","loc":[-85.599336,41.954825]},"n394490530":{"id":"n394490530","loc":[-85.597828,41.954839]},"n394490531":{"id":"n394490531","loc":[-85.597833,41.95614]},"n394490532":{"id":"n394490532","loc":[-85.596586,41.956151]},"n394490533":{"id":"n394490533","loc":[-85.596586,41.956394]},"n394490534":{"id":"n394490534","loc":[-85.595933,41.956394]},"n394490535":{"id":"n394490535","loc":[-85.595933,41.958176]},"n394490536":{"id":"n394490536","loc":[-85.597635,41.958179]},"n394490537":{"id":"n394490537","loc":[-85.597717,41.958177]},"n394490538":{"id":"n394490538","loc":[-85.601671,41.958194]},"n394490539":{"id":"n394490539","loc":[-85.605619,41.958194]},"n394490540":{"id":"n394490540","loc":[-85.608054,41.958187]},"n394490542":{"id":"n394490542","loc":[-85.6080762,41.9547864]},"n394490545":{"id":"n394490545","loc":[-85.6104354,41.9548263]},"n394490546":{"id":"n394490546","loc":[-85.610274,41.951106]},"n394490547":{"id":"n394490547","loc":[-85.610278,41.950829]},"n394490548":{"id":"n394490548","loc":[-85.610309,41.948377]},"n394490549":{"id":"n394490549","loc":[-85.610314,41.947986]},"n394490550":{"id":"n394490550","loc":[-85.610464,41.947985]},"n394490551":{"id":"n394490551","loc":[-85.610447,41.947468]},"n394490552":{"id":"n394490552","loc":[-85.612469,41.947471]},"n394490553":{"id":"n394490553","loc":[-85.612494,41.945576]},"n394490554":{"id":"n394490554","loc":[-85.610292,41.94558]},"n394490555":{"id":"n394490555","loc":[-85.608412,41.945625]},"n394490556":{"id":"n394490556","loc":[-85.608412,41.943036]},"n394490557":{"id":"n394490557","loc":[-85.608702,41.943087]},"n394490558":{"id":"n394490558","loc":[-85.609196,41.943224]},"n394490559":{"id":"n394490559","loc":[-85.609571,41.943263]},"n394490560":{"id":"n394490560","loc":[-85.610116,41.943295]},"n394490561":{"id":"n394490561","loc":[-85.610273,41.943275]},"n394490562":{"id":"n394490562","loc":[-85.611339,41.943075]},"n394490563":{"id":"n394490563","loc":[-85.611575,41.942997]},"n394490564":{"id":"n394490564","loc":[-85.611847,41.942849]},"n394490565":{"id":"n394490565","loc":[-85.612164,41.942568]},"n394490566":{"id":"n394490566","loc":[-85.612341,41.942529]},"n394490567":{"id":"n394490567","loc":[-85.612562,41.942524]},"n394490568":{"id":"n394490568","loc":[-85.612768,41.942546]},"n394490569":{"id":"n394490569","loc":[-85.612938,41.942633]},"n394490570":{"id":"n394490570","loc":[-85.6131,41.942782]},"n394490571":{"id":"n394490571","loc":[-85.613299,41.942919]},"n394490572":{"id":"n394490572","loc":[-85.613498,41.942996]},"n394490573":{"id":"n394490573","loc":[-85.614698,41.942842]},"n394490574":{"id":"n394490574","loc":[-85.615288,41.942698]},"n394490575":{"id":"n394490575","loc":[-85.616054,41.942693]},"n394490576":{"id":"n394490576","loc":[-85.61603,41.942175]},"n394490577":{"id":"n394490577","loc":[-85.616004,41.941741]},"n394490578":{"id":"n394490578","loc":[-85.615994,41.940156]},"n394490579":{"id":"n394490579","loc":[-85.615144,41.940159]},"n394490580":{"id":"n394490580","loc":[-85.614915,41.940161]},"n394490582":{"id":"n394490582","loc":[-85.614875,41.938532]},"n394490583":{"id":"n394490583","loc":[-85.616167,41.938787]},"n394490585":{"id":"n394490585","loc":[-85.616176,41.938589]},"n394490586":{"id":"n394490586","loc":[-85.614537,41.938282]},"n394490588":{"id":"n394490588","loc":[-85.610141,41.937459]},"n394490589":{"id":"n394490589","loc":[-85.610172,41.937298]},"n394490590":{"id":"n394490590","loc":[-85.609918,41.935495]},"n394490592":{"id":"n394490592","loc":[-85.610092,41.935451]},"n394490594":{"id":"n394490594","loc":[-85.610681,41.935247]},"n394490595":{"id":"n394490595","loc":[-85.611446,41.934955]},"n394490596":{"id":"n394490596","loc":[-85.612057,41.934696]},"n394490598":{"id":"n394490598","loc":[-85.613256,41.934084]},"n394490599":{"id":"n394490599","loc":[-85.613948,41.933682]},"n394490601":{"id":"n394490601","loc":[-85.61436,41.933417]},"n394490602":{"id":"n394490602","loc":[-85.614638,41.933212]},"n394490604":{"id":"n394490604","loc":[-85.615249,41.9332]},"n394490605":{"id":"n394490605","loc":[-85.618218,41.933223]},"n394490607":{"id":"n394490607","loc":[-85.618241,41.933479]},"n394490608":{"id":"n394490608","loc":[-85.618257,41.93365]},"n394490609":{"id":"n394490609","loc":[-85.618298,41.935067]},"n394490611":{"id":"n394490611","loc":[-85.619791,41.935067]},"n394490612":{"id":"n394490612","loc":[-85.619794,41.933301]},"n394490613":{"id":"n394490613","loc":[-85.619795,41.932692]},"n394490614":{"id":"n394490614","loc":[-85.619729,41.929517]},"n394490615":{"id":"n394490615","loc":[-85.619801,41.929305]},"n394490616":{"id":"n394490616","loc":[-85.619809,41.927391]},"n394490617":{"id":"n394490617","loc":[-85.620883,41.927378]},"n394490618":{"id":"n394490618","loc":[-85.620988,41.927368]},"n394490619":{"id":"n394490619","loc":[-85.621076,41.927368]},"n394490620":{"id":"n394490620","loc":[-85.621156,41.927376]},"n394490621":{"id":"n394490621","loc":[-85.621685,41.92737]},"n394490622":{"id":"n394490622","loc":[-85.624716,41.927359]},"n394490623":{"id":"n394490623","loc":[-85.625308,41.92737]},"n394490624":{"id":"n394490624","loc":[-85.625655,41.927377]},"n394490625":{"id":"n394490625","loc":[-85.625093,41.925591]},"n394490626":{"id":"n394490626","loc":[-85.625174,41.92559]},"n394490627":{"id":"n394490627","loc":[-85.625249,41.925597]},"n394490628":{"id":"n394490628","loc":[-85.625532,41.925604]},"n394490629":{"id":"n394490629","loc":[-85.625761,41.925597]},"n394490630":{"id":"n394490630","loc":[-85.625955,41.926153]},"n394490631":{"id":"n394490631","loc":[-85.626209,41.926155]},"n394490632":{"id":"n394490632","loc":[-85.627757,41.926151]},"n394490633":{"id":"n394490633","loc":[-85.627825,41.926298]},"n394490634":{"id":"n394490634","loc":[-85.627994,41.926315]},"n394490635":{"id":"n394490635","loc":[-85.628049,41.927196]},"n394490636":{"id":"n394490636","loc":[-85.62949,41.927221]},"n394490637":{"id":"n394490637","loc":[-85.629602,41.927277]},"n394490638":{"id":"n394490638","loc":[-85.6297102,41.9273279]},"n394490639":{"id":"n394490639","loc":[-85.630958,41.927398]},"n394490699":{"id":"n394490699","loc":[-85.632741,41.927388]},"n394490700":{"id":"n394490700","loc":[-85.632997,41.927391]},"n394490701":{"id":"n394490701","loc":[-85.633149,41.927393]},"n394490702":{"id":"n394490702","loc":[-85.633334,41.927393]},"n394490703":{"id":"n394490703","loc":[-85.633468,41.927561]},"n394490704":{"id":"n394490704","loc":[-85.633563,41.927755]},"n394490705":{"id":"n394490705","loc":[-85.633662,41.928192]},"n394490706":{"id":"n394490706","loc":[-85.633679,41.928807]},"n394490707":{"id":"n394490707","loc":[-85.633687,41.929107]},"n394490708":{"id":"n394490708","loc":[-85.633927,41.929109]},"n394490709":{"id":"n394490709","loc":[-85.634126,41.929111]},"n394490710":{"id":"n394490710","loc":[-85.634207,41.92911]},"n394490711":{"id":"n394490711","loc":[-85.634323,41.929111]},"n394490712":{"id":"n394490712","loc":[-85.636712,41.929128]},"n394490713":{"id":"n394490713","loc":[-85.63808,41.9291]},"n394490714":{"id":"n394490714","loc":[-85.639213,41.929088]},"n394490715":{"id":"n394490715","loc":[-85.639189,41.92852]},"n394490716":{"id":"n394490716","loc":[-85.639204,41.925488]},"n394490717":{"id":"n394490717","loc":[-85.644204,41.925452]},"n394490718":{"id":"n394490718","loc":[-85.651425,41.925406]},"n394490719":{"id":"n394490719","loc":[-85.651449,41.926321]},"n394490720":{"id":"n394490720","loc":[-85.651451,41.926969]},"n394490721":{"id":"n394490721","loc":[-85.651458,41.928052]},"n394490722":{"id":"n394490722","loc":[-85.651446,41.928892]},"n394490723":{"id":"n394490723","loc":[-85.651456,41.929447]},"n394490724":{"id":"n394490724","loc":[-85.651707,41.929454]},"n394490725":{"id":"n394490725","loc":[-85.652369,41.929473]},"n394490726":{"id":"n394490726","loc":[-85.6525,41.929452]},"n394490727":{"id":"n394490727","loc":[-85.654066,41.92946]},"n394490728":{"id":"n394490728","loc":[-85.654816,41.92946]},"n394490729":{"id":"n394490729","loc":[-85.654816,41.930337]},"n394490730":{"id":"n394490730","loc":[-85.654587,41.930337]},"n394490731":{"id":"n394490731","loc":[-85.654548,41.931072]},"n394490732":{"id":"n394490732","loc":[-85.654538,41.931701]},"n394490733":{"id":"n394490733","loc":[-85.654898,41.931689]},"n394490734":{"id":"n394490734","loc":[-85.654898,41.932505]},"n394490735":{"id":"n394490735","loc":[-85.654854,41.932514]},"n394490736":{"id":"n394490736","loc":[-85.655497,41.932499]},"n394490737":{"id":"n394490737","loc":[-85.656405,41.932493]},"n394490738":{"id":"n394490738","loc":[-85.656422,41.933416]},"n394490739":{"id":"n394490739","loc":[-85.657322,41.933438]},"n1475293233":{"id":"n1475293233","loc":[-85.6385522,41.9585167]},"n1475293242":{"id":"n1475293242","loc":[-85.64609,41.9540815]},"n1475293249":{"id":"n1475293249","loc":[-85.6358079,41.9692721]},"n1475293256":{"id":"n1475293256","loc":[-85.6387369,41.9581583]},"n1475293259":{"id":"n1475293259","loc":[-85.6455882,41.9541138]},"n1475293266":{"id":"n1475293266","loc":[-85.6451008,41.9541821]},"n1819800253":{"id":"n1819800253","loc":[-85.6134286,41.9429692]},"n2114807558":{"id":"n2114807558","loc":[-85.6365609,41.963866],"tags":{"railway":"level_crossing"}},"n2189015728":{"id":"n2189015728","loc":[-85.6383956,41.9590576]},"n2189015838":{"id":"n2189015838","loc":[-85.6435144,41.9563705]},"n2189015842":{"id":"n2189015842","loc":[-85.6415782,41.9557035]},"n2189015855":{"id":"n2189015855","loc":[-85.6440829,41.9554577]},"n2199109849":{"id":"n2199109849","loc":[-85.6393434,41.9565591]},"n2199109851":{"id":"n2199109851","loc":[-85.6393208,41.9565002]},"n2199109857":{"id":"n2199109857","loc":[-85.6401986,41.955545]},"n2199109859":{"id":"n2199109859","loc":[-85.6402362,41.955587]},"n2199109861":{"id":"n2199109861","loc":[-85.6395958,41.9565675]},"n2199109863":{"id":"n2199109863","loc":[-85.639528,41.9566011]},"w209717053":{"id":"w209717053","tags":{"area":"yes","building":"yes"},"nodes":["n2199109829","n2199109831","n2199109833","n2199109835","n2199109829"]},"w17966415":{"id":"w17966415","tags":{"access":"private","highway":"service","name":"Manufacturing Way"},"nodes":["n185971642","n185977232","n185977233","n185949745","n185949748","n185977234"]},"w209717054":{"id":"w209717054","tags":{"area":"yes","building":"yes"},"nodes":["n2199109837","n2199109839","n2199109841","n2199109843","n2199109845","n2199109847","n2199109837"]},"w208627214":{"id":"w208627214","tags":{"highway":"service"},"nodes":["n185949755","n2189015728","n1475293233","n1475293256","n185952163","n185952161","n185952160","n185952158","n185949763","n1819848965","n1819848890","n185952156"]},"w17963817":{"id":"w17963817","tags":{"access":"private","highway":"service"},"nodes":["n185949765","n185953413","n185953417","n185953421","n185953423"]},"w34369809":{"id":"w34369809","tags":{"admin_level":"8","boundary":"administrative","landuse":"residential"},"nodes":["n394490395","n394490396","n394490397","n394490398","n394490399","n394490400","n394490401","n394490402","n394490403","n394490404","n394490405","n394490406","n394490407","n394490408","n394490409","n394490410","n394490411","n394490412","n394490413","n394490414","n394490415","n394490416","n394490417","n394490418","n394490419","n394490420","n394490421","n394490422","n394490423","n394490424","n394490425","n394490426","n394490427","n394490428","n1475293242","n1475293259","n1475293266","n394490429","n394490430","n394490431","n394490432","n394490433","n394490434","n394490435","n394490436","n394490437","n394490438","n394490439","n394490440","n394490441","n394490442","n394490443","n394490444","n394490445","n394490446","n1475293249","n394490447","n394490448","n394490449","n394490450","n394490451","n394490452","n394490453","n394490454","n394490455","n394490456","n394490457","n394490458","n394490459","n394490460","n394490461","n394490462","n2114807558","n394490463","n1475293226","n394490464","n394490465","n394490466","n394490467","n394490468","n394490469","n394490470","n394490471","n394490472","n394490473","n394490474","n394490475","n394490476","n394490477","n394490478","n394490479","n394490480","n394490481","n394490482","n394490483","n394490484","n394490485","n394490486","n394490487","n394490488","n394490489","n394490490","n394490491","n394490492","n394490493","n394490494","n394490495","n394490496","n394490497","n394490498","n394490499","n394490500","n394490501","n394490502","n394490503","n394490504","n394490505","n394490506","n394490507","n394490508","n394490509","n394490510","n394490511","n394490512","n394490513","n394490514","n394490515","n394490516","n394490517","n394490518","n394490519","n394490520","n394490521","n394490522","n394490523","n394490524","n394490525","n394490526","n394490527","n394490528","n394490529","n394490530","n394490531","n394490532","n394490533","n394490534","n394490535","n394490536","n394490537","n394490538","n394490539","n394490540","n394490542","n394490545","n394490546","n394490547","n394490548","n394490549","n394490550","n394490551","n394490552","n394490553","n394490554","n394490555","n394490556","n394490557","n394490558","n394490559","n394490560","n394490561","n394490562","n394490563","n394490564","n394490565","n394490566","n394490567","n394490568","n394490569","n394490570","n394490571","n1819800253","n394490572","n394490573","n394490574","n394490575","n394490576","n394490577","n394490578","n394490579","n394490580","n394490582","n394490583","n394490585","n394490586","n394490588","n394490589","n394490590","n394490592","n394490594","n394490595","n394490596","n394490598","n394490599","n394490601","n394490602","n394490604","n394490605","n394490607","n394490608","n394490609","n394490611","n394490612","n394490613","n394490614","n394490615","n394490616","n394490617","n394490618","n394490619","n394490620","n394490621","n394490622","n394490623","n394490624","n394490625","n394490626","n394490627","n394490628","n394490629","n394490630","n394490631","n394490632","n394490633","n394490634","n394490635","n394490636","n394490637","n394490638","n394490639","n394490699","n394490700","n394490701","n394490702","n394490703","n394490704","n394490705","n394490706","n394490707","n394490708","n394490709","n394490710","n394490711","n394490712","n394490713","n394490714","n394490715","n394490716","n394490717","n394490718","n394490719","n394490720","n394490721","n394490722","n394490723","n394490724","n394490725","n394490726","n394490727","n394490728","n394490729","n394490730","n394490731","n394490732","n394490733","n394490734","n394490735","n394490736","n394490737","n394490738","n394490739","n394490395"]},"w208627221":{"id":"w208627221","tags":{"amenity":"parking","area":"yes"},"nodes":["n2189015838","n2189015842","n2189015846","n2189015849","n2189015852","n2189015855","n2189015838"]},"w209717052":{"id":"w209717052","tags":{"area":"yes","building":"yes"},"nodes":["n2199109816","n2199109818","n2199109820","n2199109822","n2199109825","n2199109827","n2199109816"]},"w134151784":{"id":"w134151784","tags":{"bridge":"yes","highway":"residential","name":"W Hoffman St"},"nodes":["n185971648","n185971651"]},"w209717055":{"id":"w209717055","tags":{"area":"yes","landuse":"basin"},"nodes":["n2199109849","n2199109851","n2199109853","n2199109855","n2199109857","n2199109859","n2199109861","n2199109863","n2199109849"]},"w17967763":{"id":"w17967763","tags":{"highway":"residential","name":"Rock River Ave"},"nodes":["n1475293244","n185982166","n185975067","n185971637"]},"r134949":{"id":"r134949","tags":{"admin_level":"8","border_type":"city","boundary":"administrative","name":"Three Rivers","place":"city","type":"boundary"},"members":[{"id":"w34369809","type":"way","role":"outer"},{"id":"w34369821","type":"way","role":"outer"},{"id":"w34369822","type":"way","role":"outer"},{"id":"w34369823","type":"way","role":"outer"},{"id":"w34369824","type":"way","role":"outer"},{"id":"w34369825","type":"way","role":"outer"},{"id":"w34369826","type":"way","role":"outer"},{"id":"w34369810","type":"way","role":"inner"},{"id":"w34369811","type":"way","role":"inner"},{"id":"w34369812","type":"way","role":"inner"},{"id":"w34367079","type":"way","role":"inner"},{"id":"w34369814","type":"way","role":"inner"},{"id":"w34367080","type":"way","role":"inner"},{"id":"w34369815","type":"way","role":"inner"},{"id":"w34369820","type":"way","role":"inner"}]},"n1819848881":{"id":"n1819848881","loc":[-85.638562,41.9569965]},"n1819848947":{"id":"n1819848947","loc":[-85.6384348,41.9576565]},"n1819849044":{"id":"n1819849044","loc":[-85.6385749,41.9573345]},"n2114807547":{"id":"n2114807547","loc":[-85.6384626,41.9583756]},"n2114807564":{"id":"n2114807564","loc":[-85.638535,41.9581283]},"n2189015691":{"id":"n2189015691","loc":[-85.6435584,41.9565243]},"n2189015696":{"id":"n2189015696","loc":[-85.6435805,41.9566049]},"n2189015722":{"id":"n2189015722","loc":[-85.6435035,41.9567438]},"n2189015744":{"id":"n2189015744","loc":[-85.6437991,41.9569582]},"n2189015747":{"id":"n2189015747","loc":[-85.6433042,41.9567742]},"n2189015750":{"id":"n2189015750","loc":[-85.6433827,41.9566844]},"n2189015753":{"id":"n2189015753","loc":[-85.6430447,41.9565588]},"n2189015756":{"id":"n2189015756","loc":[-85.6431111,41.956451]},"n2189015759":{"id":"n2189015759","loc":[-85.6420247,41.956083]},"n2189015760":{"id":"n2189015760","loc":[-85.6419945,41.9561369]},"n2189015764":{"id":"n2189015764","loc":[-85.6413729,41.9558945]},"n2189015766":{"id":"n2189015766","loc":[-85.6412884,41.9560606]},"n2189015770":{"id":"n2189015770","loc":[-85.6411798,41.9560112]},"n2189015771":{"id":"n2189015771","loc":[-85.6410651,41.9562132]},"n2189015774":{"id":"n2189015774","loc":[-85.6409504,41.9561728]},"n2189015778":{"id":"n2189015778","loc":[-85.6407996,41.9564241]},"n2189015781":{"id":"n2189015781","loc":[-85.6406889,41.9563892]},"n2189015785":{"id":"n2189015785","loc":[-85.6404857,41.9567024]},"n2189015789":{"id":"n2189015789","loc":[-85.6406909,41.9567877]},"n2189015793":{"id":"n2189015793","loc":[-85.6405642,41.9570165]},"n2189015796":{"id":"n2189015796","loc":[-85.6415359,41.9573711]},"n2189015800":{"id":"n2189015800","loc":[-85.6411738,41.9579501]},"n2189015804":{"id":"n2189015804","loc":[-85.6411119,41.957921]},"n2189015808":{"id":"n2189015808","loc":[-85.6403186,41.9591751]},"n2189015909":{"id":"n2189015909","loc":[-85.6389293,41.9564636]},"n2189015926":{"id":"n2189015926","loc":[-85.6385431,41.9564617]},"n2189015929":{"id":"n2189015929","loc":[-85.6385457,41.9561823]},"n2189015932":{"id":"n2189015932","loc":[-85.6389319,41.9561843]},"n2199109865":{"id":"n2199109865","loc":[-85.6400768,41.956776]},"n2199109867":{"id":"n2199109867","loc":[-85.639902,41.9567153]},"n2199109869":{"id":"n2199109869","loc":[-85.640004,41.956553]},"n2199109871":{"id":"n2199109871","loc":[-85.6401788,41.9566137]},"n2199109873":{"id":"n2199109873","loc":[-85.6399316,41.9564506],"tags":{"man_made":"water_tower"}},"n2199109876":{"id":"n2199109876","loc":[-85.6397689,41.9572354]},"n2199109878":{"id":"n2199109878","loc":[-85.6399229,41.9569826]},"n2199109880":{"id":"n2199109880","loc":[-85.639706,41.9569095]},"n2199109882":{"id":"n2199109882","loc":[-85.639552,41.9571623]},"n2199109884":{"id":"n2199109884","loc":[-85.6391028,41.9569517]},"n2199109886":{"id":"n2199109886","loc":[-85.6392876,41.956646]},"n2199109888":{"id":"n2199109888","loc":[-85.639484,41.9567117]},"n2199109889":{"id":"n2199109889","loc":[-85.6394322,41.9567973]},"n2199109890":{"id":"n2199109890","loc":[-85.6393718,41.9567771]},"n2199109891":{"id":"n2199109891","loc":[-85.6392387,41.9569972]},"n1819848900":{"id":"n1819848900","loc":[-85.638281,41.9576578]},"n1819848978":{"id":"n1819848978","loc":[-85.6377186,41.9580867]},"n1819849039":{"id":"n1819849039","loc":[-85.6384217,41.9573405]},"n1819849050":{"id":"n1819849050","loc":[-85.6377011,41.9570042]},"n1819849088":{"id":"n1819849088","loc":[-85.6382879,41.9580817]},"n2114807549":{"id":"n2114807549","loc":[-85.6362551,41.96473]},"n2114807587":{"id":"n2114807587","loc":[-85.6368694,41.9629829]},"n2189015725":{"id":"n2189015725","loc":[-85.644156,41.9569753]},"n2189015741":{"id":"n2189015741","loc":[-85.6419825,41.9597632]},"w208627217":{"id":"w208627217","tags":{"area":"yes","building":"yes"},"nodes":["n2189015741","n2189015744","n2189015747","n2189015750","n2189015753","n2189015756","n2189015759","n2189015760","n2189015764","n2189015766","n2189015770","n2189015771","n2189015774","n2189015778","n2189015781","n2189015785","n2189015789","n2189015793","n2189015796","n2189015800","n2189015804","n2189015808","n2189015741"]},"w208627212":{"id":"w208627212","tags":{"highway":"service"},"nodes":["n2189015691","n2189015696","n2189015722","n2189015725"]},"w209717057":{"id":"w209717057","tags":{"area":"yes","building":"yes"},"nodes":["n2199109876","n2199109878","n2199109880","n2199109882","n2199109876"]},"w209717056":{"id":"w209717056","tags":{"area":"yes","building":"yes"},"nodes":["n2199109865","n2199109867","n2199109869","n2199109871","n2199109865"]},"w208627231":{"id":"w208627231","tags":{"area":"yes","building":"yes"},"nodes":["n2189015909","n2189015926","n2189015929","n2189015932","n2189015909"]},"w170848326":{"id":"w170848326","tags":{"building":"yes"},"nodes":["n1819848881","n1819849050","n1819848978","n1819849088","n1819848900","n1819848947","n1819849039","n1819849044","n1819848881"]},"w17963182":{"id":"w17963182","tags":{"highway":"service"},"nodes":["n185949763","n185949765","n2189015691","n185949745"]},"w201484340":{"id":"w201484340","tags":{"railway":"rail","service":"siding"},"nodes":["n2114807565","n2114807564","n2114807547","n2114807587","n2114807558","n2114807549","n2114807593"]},"w209717058":{"id":"w209717058","tags":{"area":"yes","building":"yes"},"nodes":["n2199109884","n2199109886","n2199109888","n2199109889","n2199109890","n2199109891","n2199109884"]},"n185954650":{"id":"n185954650","loc":[-85.627331,41.957439]},"n185966949":{"id":"n185966949","loc":[-85.626868,41.957314]},"n185989335":{"id":"n185989335","loc":[-85.62529,41.958568]},"n185989337":{"id":"n185989337","loc":[-85.624962,41.958453]},"n185989339":{"id":"n185989339","loc":[-85.624832,41.958399]},"n185989340":{"id":"n185989340","loc":[-85.624707,41.958325]},"n185989342":{"id":"n185989342","loc":[-85.624636,41.958251]},"n185989345":{"id":"n185989345","loc":[-85.624578,41.95818]},"n185989347":{"id":"n185989347","loc":[-85.624533,41.958099]},"n185989349":{"id":"n185989349","loc":[-85.624507,41.957985]},"n185989351":{"id":"n185989351","loc":[-85.624495,41.957807]},"n185989353":{"id":"n185989353","loc":[-85.624514,41.957663]},"n185989354":{"id":"n185989354","loc":[-85.624577,41.957593]},"n185989356":{"id":"n185989356","loc":[-85.624685,41.95754]},"n185989357":{"id":"n185989357","loc":[-85.624802,41.957523]},"n185989359":{"id":"n185989359","loc":[-85.624996,41.957524]},"n185989361":{"id":"n185989361","loc":[-85.625409,41.957515]},"n185989364":{"id":"n185989364","loc":[-85.625634,41.957496]},"n185989367":{"id":"n185989367","loc":[-85.625832,41.957453]},"n185989368":{"id":"n185989368","loc":[-85.626044,41.957394]},"n354031352":{"id":"n354031352","loc":[-85.6252778,41.9586111],"tags":{"amenity":"place_of_worship","denomination":"baptist","name":"First Baptist Church","religion":"christian"}},"n2199109892":{"id":"n2199109892","loc":[-85.6261578,41.9589963]},"n2199109893":{"id":"n2199109893","loc":[-85.6263191,41.9586865]},"n2199109894":{"id":"n2199109894","loc":[-85.6261186,41.9586288]},"n2199109895":{"id":"n2199109895","loc":[-85.6260644,41.9587329]},"n2199109896":{"id":"n2199109896","loc":[-85.6261547,41.9587589]},"n2199109898":{"id":"n2199109898","loc":[-85.6260476,41.9589646]},"n185966951":{"id":"n185966951","loc":[-85.628404,41.957438]},"w17965351":{"id":"w17965351","tags":{"highway":"residential","name":"Flower Street"},"nodes":["n185966948","n185966949","n185954650","n185966951","n185966953","n185966955","n185966957"]},"w17967809":{"id":"w17967809","tags":{"highway":"residential","name":"Azaleamum Drive"},"nodes":["n185982197","n185989335","n185989337","n185989339","n185989340","n185989342","n185989345","n185989347","n185989349","n185989351","n185989353","n185989354","n185989356","n185989357","n185989359","n185989361","n185989364","n185989367","n185989368","n185982196"]},"w209717059":{"id":"w209717059","tags":{"area":"yes","building":"yes"},"nodes":["n2199109892","n2199109893","n2199109894","n2199109895","n2199109896","n2199109898","n2199109892"]},"n185961390":{"id":"n185961390","loc":[-85.63137,41.959033]},"n185961393":{"id":"n185961393","loc":[-85.634315,41.959017]},"w17966214":{"id":"w17966214","tags":{"highway":"residential","name":"East Adams Street"},"nodes":["n185975351","n185967434","n185968108"]},"w17964793":{"id":"w17964793","tags":{"highway":"residential","name":"Morris Ave"},"nodes":["n185961389","n185961390","n185961391","n185961393","n185961396"]},"n185952166":{"id":"n185952166","loc":[-85.638174,41.95831]},"n2114807552":{"id":"n2114807552","loc":[-85.6383526,41.9593788]},"n2114807591":{"id":"n2114807591","loc":[-85.6383741,41.9593968]},"n2189015731":{"id":"n2189015731","loc":[-85.6368404,41.9592785]},"n2189015734":{"id":"n2189015734","loc":[-85.6368404,41.9585918]},"n2189015737":{"id":"n2189015737","loc":[-85.6376009,41.9585918]},"n2189015738":{"id":"n2189015738","loc":[-85.6376009,41.9592785]},"n2189015897":{"id":"n2189015897","loc":[-85.6376839,41.9566137]},"n2189015900":{"id":"n2189015900","loc":[-85.6376831,41.9564865]},"n2189015903":{"id":"n2189015903","loc":[-85.6381161,41.9564851]},"n2189015906":{"id":"n2189015906","loc":[-85.6381168,41.9566122]},"n2189015937":{"id":"n2189015937","loc":[-85.6364789,41.9590634]},"n2189015940":{"id":"n2189015940","loc":[-85.6361137,41.9590672]},"n2189015943":{"id":"n2189015943","loc":[-85.6361169,41.9594033]},"n2189015945":{"id":"n2189015945","loc":[-85.6363456,41.9594021]},"n2189015952":{"id":"n2189015952","loc":[-85.636112,41.958892]},"n2189015955":{"id":"n2189015955","loc":[-85.6364757,41.9588894]},"n2189015957":{"id":"n2189015957","loc":[-85.6364729,41.9586747]},"n2189015958":{"id":"n2189015958","loc":[-85.6361103,41.9586765]},"n2189015959":{"id":"n2189015959","loc":[-85.6364719,41.9585562]},"n2189015960":{"id":"n2189015960","loc":[-85.6361093,41.958558]},"n2189015961":{"id":"n2189015961","loc":[-85.6355494,41.9586403]},"n2189015962":{"id":"n2189015962","loc":[-85.635549,41.9584711]},"n2189015963":{"id":"n2189015963","loc":[-85.6351831,41.9584715]},"n2189015964":{"id":"n2189015964","loc":[-85.6351834,41.9586408]},"n2189015966":{"id":"n2189015966","loc":[-85.6359579,41.9586359]},"n2189015968":{"id":"n2189015968","loc":[-85.6359561,41.9585465]},"n2189015971":{"id":"n2189015971","loc":[-85.6355476,41.9585509]},"n2189015974":{"id":"n2189015974","loc":[-85.6359516,41.9592934]},"n2189015977":{"id":"n2189015977","loc":[-85.635949,41.9586697]},"n2189015980":{"id":"n2189015980","loc":[-85.6351329,41.9586716]},"n2189015983":{"id":"n2189015983","loc":[-85.6351318,41.9583949]},"n2189015986":{"id":"n2189015986","loc":[-85.6349148,41.9583954]},"n2189015989":{"id":"n2189015989","loc":[-85.6349186,41.9592958]},"n2189015995":{"id":"n2189015995","loc":[-85.6360173,41.9593286]},"n2189015998":{"id":"n2189015998","loc":[-85.6360278,41.9583079]},"n2114807550":{"id":"n2114807550","loc":[-85.6383392,41.9595404]},"n2114807551":{"id":"n2114807551","loc":[-85.6375855,41.9616107]},"n2114807559":{"id":"n2114807559","loc":[-85.6373978,41.9621273]},"n2114807562":{"id":"n2114807562","loc":[-85.6373361,41.9622609]},"n2114807563":{"id":"n2114807563","loc":[-85.6376472,41.9613953]},"n2114807574":{"id":"n2114807574","loc":[-85.636974,41.9627695]},"n2114807589":{"id":"n2114807589","loc":[-85.6383017,41.9595005]},"n2114807592":{"id":"n2114807592","loc":[-85.6377169,41.9613494]},"n2114807595":{"id":"n2114807595","loc":[-85.6371081,41.962574]},"n2189015934":{"id":"n2189015934","loc":[-85.6364855,41.9595098]},"n2189015949":{"id":"n2189015949","loc":[-85.6363466,41.9595105]},"w208627244":{"id":"w208627244","tags":{"highway":"service"},"nodes":["n2189015992","n2189015995","n2189015998"]},"w208627240":{"id":"w208627240","tags":{"area":"yes","building":"yes"},"nodes":["n2189015961","n2189015971","n2189015962","n2189015963","n2189015964","n2189015961"]},"w17967437":{"id":"w17967437","tags":{"highway":"residential","name":"Lyman St"},"nodes":["n185964361","n185984024"]},"w208627237":{"id":"w208627237","tags":{"area":"yes","building":"yes"},"nodes":["n2189015955","n2189015957","n2189015958","n2189015952","n2189015955"]},"w17967465":{"id":"w17967465","tags":{"highway":"residential","name":"W Adams St"},"nodes":["n185978394","n185984022","n185964360"]},"w208627228":{"id":"w208627228","tags":{"area":"yes","building":"yes"},"nodes":["n2189015897","n2189015900","n2189015903","n2189015906","n2189015897"]},"w201484351":{"id":"w201484351","tags":{"railway":"rail","service":"siding"},"nodes":["n2114807587","n2114807574","n2114807595","n2114807562","n2114807559","n2114807551","n2114807563","n2114807589","n2114807552"]},"w208627239":{"id":"w208627239","tags":{"area":"yes","building":"yes"},"nodes":["n2189015957","n2189015959","n2189015960","n2189015958","n2189015957"]},"w208627233":{"id":"w208627233","tags":{"area":"yes","building":"yes"},"nodes":["n2189015934","n2189015937","n2189015940","n2189015943","n2189015945","n2189015949","n2189015934"]},"w208627241":{"id":"w208627241","tags":{"area":"yes","building":"yes"},"nodes":["n2189015961","n2189015966","n2189015968","n2189015971","n2189015961"]},"w17967970":{"id":"w17967970","tags":{"highway":"residential","name":"Adams St"},"nodes":["n185975351","n185978394"]},"w208627235":{"id":"w208627235","tags":{"area":"yes","building":"yes"},"nodes":["n2189015940","n2189015952","n2189015955","n2189015937","n2189015940"]},"w17965468":{"id":"w17965468","tags":{"highway":"residential","name":"Armstrong Blvd"},"nodes":["n185967917","n2189015998","n185967918","n185964362","n185952166"]},"w201484346":{"id":"w201484346","tags":{"railway":"rail","service":"siding"},"nodes":["n2114807551","n2114807592","n2114807550","n2114807591"]},"w208627242":{"id":"w208627242","tags":{"amenity":"parking","area":"yes"},"nodes":["n2189015974","n2189015977","n2189015980","n2189015983","n2189015986","n2189015989","n2189015974"]},"w208627216":{"id":"w208627216","tags":{"area":"yes","building":"yes"},"nodes":["n2189015731","n2189015734","n2189015737","n2189015738","n2189015731"]},"n185984309":{"id":"n185984309","loc":[-85.631421,41.961494]},"n185987987":{"id":"n185987987","loc":[-85.631456,41.960673]},"n185965397":{"id":"n185965397","loc":[-85.634603,41.959838]},"w17965196":{"id":"w17965196","tags":{"highway":"residential","name":"Burke Ave"},"nodes":["n185965395","n185965397","n185965399"]},"w17967215":{"id":"w17967215","tags":{"highway":"residential","name":"Kellogg Ave"},"nodes":["n185968114","n185984309","n185967440","n185978402"]},"w17967597":{"id":"w17967597","tags":{"highway":"residential","name":"Barnard Ave"},"nodes":["n185968112","n185987987","n185967438","n185978399"]},"n394490857":{"id":"n394490857","loc":[-85.633952,41.960664]},"n394490858":{"id":"n394490858","loc":[-85.633938,41.960227]},"n394490859":{"id":"n394490859","loc":[-85.634794,41.960212]},"n394490860":{"id":"n394490860","loc":[-85.634815,41.960662]},"n394490861":{"id":"n394490861","loc":[-85.634103,41.961268]},"n394490862":{"id":"n394490862","loc":[-85.634103,41.961001]},"n394490863":{"id":"n394490863","loc":[-85.634504,41.961003]},"n394490864":{"id":"n394490864","loc":[-85.634561,41.961269]},"n1057629869":{"id":"n1057629869","loc":[-85.6382599,41.9612134]},"n1057629937":{"id":"n1057629937","loc":[-85.6380035,41.9616137]},"n2189016014":{"id":"n2189016014","loc":[-85.6360365,41.9626496]},"n2189016017":{"id":"n2189016017","loc":[-85.6360374,41.9623228]},"n2189016020":{"id":"n2189016020","loc":[-85.6367557,41.9623239]},"n2189016022":{"id":"n2189016022","loc":[-85.6367566,41.9619919]},"n2189016025":{"id":"n2189016025","loc":[-85.6351794,41.9619893]},"n2189016028":{"id":"n2189016028","loc":[-85.6351788,41.9622011]},"n2189016031":{"id":"n2189016031","loc":[-85.6350855,41.9622009]},"n2189016034":{"id":"n2189016034","loc":[-85.6350845,41.962527]},"n2189016037":{"id":"n2189016037","loc":[-85.6352732,41.9625273]},"n2189016039":{"id":"n2189016039","loc":[-85.6352738,41.9623178]},"n2189016042":{"id":"n2189016042","loc":[-85.6357712,41.9623186]},"n2189016044":{"id":"n2189016044","loc":[-85.6357702,41.9626492]},"n1057629880":{"id":"n1057629880","loc":[-85.638817,41.9619017]},"n1057629923":{"id":"n1057629923","loc":[-85.6390733,41.9615014]},"w91092312":{"id":"w91092312","tags":{"power":"station"},"nodes":["n1057629923","n1057629869","n1057629937","n1057629880","n1057629923"]},"w34369826":{"id":"w34369826","tags":{"admin_level":"8","boundary":"administrative"},"nodes":["n394490861","n394490862","n394490863","n394490864","n394490861"]},"w34369825":{"id":"w34369825","tags":{"admin_level":"8","boundary":"administrative"},"nodes":["n394490857","n394490858","n394490859","n394490860","n394490857"]},"w208627248":{"id":"w208627248","tags":{"area":"yes","building":"yes"},"nodes":["n2189016014","n2189016017","n2189016020","n2189016022","n2189016025","n2189016028","n2189016031","n2189016034","n2189016037","n2189016039","n2189016042","n2189016044","n2189016014"]},"n394490766":{"id":"n394490766","loc":[-85.616777,41.955642]},"n394490768":{"id":"n394490768","loc":[-85.617239,41.955644]},"n394490792":{"id":"n394490792","loc":[-85.619034,41.95543]},"n185972055":{"id":"n185972055","loc":[-85.6185905,41.9568211]},"n185972057":{"id":"n185972057","loc":[-85.6186688,41.9570086]},"n185972059":{"id":"n185972059","loc":[-85.6186924,41.9581453]},"n185972060":{"id":"n185972060","loc":[-85.6187082,41.9588211],"tags":{"highway":"turning_circle"}},"n1819790724":{"id":"n1819790724","loc":[-85.6182155,41.9555703]},"n1819790735":{"id":"n1819790735","loc":[-85.6184059,41.9566188]},"n1819790799":{"id":"n1819790799","loc":[-85.6182372,41.9563771]},"n1819790896":{"id":"n1819790896","loc":[-85.6181431,41.9557227]},"n185971405":{"id":"n185971405","loc":[-85.6186766,41.9577468]},"n185971565":{"id":"n185971565","loc":[-85.6181613,41.9560879]},"n185967985":{"id":"n185967985","loc":[-85.6186798,41.9585791]},"n185955753":{"id":"n185955753","loc":[-85.620773,41.9555854]},"n185955755":{"id":"n185955755","loc":[-85.6212652,41.9559891]},"n185955748":{"id":"n185955748","loc":[-85.620722,41.954858]},"n185955751":{"id":"n185955751","loc":[-85.6206912,41.955367]},"n185967987":{"id":"n185967987","loc":[-85.6159351,41.9585809]},"n185971407":{"id":"n185971407","loc":[-85.6159142,41.9577578]},"n185971570":{"id":"n185971570","loc":[-85.6162248,41.95603]},"n185971572":{"id":"n185971572","loc":[-85.6160402,41.9560749]},"n185971574":{"id":"n185971574","loc":[-85.61593,41.956201]},"n185981301":{"id":"n185981301","loc":[-85.6158973,41.9581601]},"n394490762":{"id":"n394490762","loc":[-85.617193,41.954706]},"n394490764":{"id":"n394490764","loc":[-85.616773,41.954737]},"n394490787":{"id":"n394490787","loc":[-85.618972,41.954737]},"n394490790":{"id":"n394490790","loc":[-85.619046,41.954929]},"n394490794":{"id":"n394490794","loc":[-85.619922,41.955296]},"n394490796":{"id":"n394490796","loc":[-85.61991,41.95501]},"n394490798":{"id":"n394490798","loc":[-85.619974,41.954751]},"n1819790677":{"id":"n1819790677","loc":[-85.6187031,41.9550522]},"n1819790787":{"id":"n1819790787","loc":[-85.6186436,41.9552022]},"n1819790828":{"id":"n1819790828","loc":[-85.6185127,41.9553393]},"w17966857":{"id":"w17966857","tags":{"access":"private","highway":"service","name":"Sable River Rd"},"nodes":["n185972059","n185981301"]},"w34369814":{"id":"w34369814","tags":{"admin_level":"8","boundary":"administrative"},"nodes":["n394490787","n394490790","n394490792","n394490794","n394490796","n394490798","n394490787"]},"w17964176":{"id":"w17964176","tags":{"highway":"residential"},"nodes":["n185955747","n185955748","n185955751","n185955753","n185955755"]},"w17965838":{"id":"w17965838","tags":{"access":"private","highway":"service","name":"Pine River Rd"},"nodes":["n185971405","n185971407"]},"w17965476":{"id":"w17965476","tags":{"access":"private","highway":"service","name":"Raisin River Rd"},"nodes":["n185967985","n185967987"]},"w17965913":{"id":"w17965913","tags":{"access":"private","highway":"service","name":"Shiawassee River Rd"},"nodes":["n185972054","n1819790677","n1819790787","n1819790828","n1819790724","n1819790896","n185971565","n1819790799","n1819790735","n185972055","n185972057","n185971405","n185972059","n185967985","n185972060"]},"w34369811":{"id":"w34369811","tags":{"admin_level":"8","boundary":"administrative"},"nodes":["n394490762","n394490764","n394490766","n394490768","n394490762"]},"w17965854":{"id":"w17965854","tags":{"access":"private","highway":"service","name":"Sturgeon River Rd"},"nodes":["n185971565","n185971570","n185971572","n185971574"]},"n2139795769":{"id":"n2139795769","loc":[-85.6250804,41.9608796]},"n2139795770":{"id":"n2139795770","loc":[-85.6250315,41.9613684]},"n2139795771":{"id":"n2139795771","loc":[-85.6249671,41.9614362]},"n2139795772":{"id":"n2139795772","loc":[-85.6249698,41.961522]},"n2139795773":{"id":"n2139795773","loc":[-85.6250798,41.9615838]},"n2139795774":{"id":"n2139795774","loc":[-85.6252273,41.9615639]},"n2139795775":{"id":"n2139795775","loc":[-85.6252863,41.9614622]},"n2139795776":{"id":"n2139795776","loc":[-85.6252273,41.9613764]},"n2139795777":{"id":"n2139795777","loc":[-85.6251227,41.9613525]},"n2139795778":{"id":"n2139795778","loc":[-85.6249564,41.9612527]},"n2139795779":{"id":"n2139795779","loc":[-85.6249846,41.9610254]},"n2139795780":{"id":"n2139795780","loc":[-85.6266725,41.9599647]},"n2139795781":{"id":"n2139795781","loc":[-85.6259162,41.9599711]},"n2139795782":{"id":"n2139795782","loc":[-85.6257185,41.960019]},"n2139795783":{"id":"n2139795783","loc":[-85.6255509,41.9601213]},"n185963539":{"id":"n185963539","loc":[-85.615718,41.983893]},"n185964418":{"id":"n185964418","loc":[-85.616626,42.049512]},"n185966614":{"id":"n185966614","loc":[-85.615514,41.976603]},"n185966635":{"id":"n185966635","loc":[-85.616118,42.013017]},"n185969040":{"id":"n185969040","loc":[-85.615632,41.972357]},"n185969070":{"id":"n185969070","loc":[-85.619145,41.967648]},"n185972156":{"id":"n185972156","loc":[-85.621894,41.963956]},"n185972157":{"id":"n185972157","loc":[-85.621806,41.964077]},"n185972158":{"id":"n185972158","loc":[-85.620848,41.965341]},"n185972159":{"id":"n185972159","loc":[-85.620684,41.965558]},"n185972160":{"id":"n185972160","loc":[-85.620621,41.965658]},"n185972161":{"id":"n185972161","loc":[-85.617844,41.969359]},"n185972162":{"id":"n185972162","loc":[-85.616843,41.97068]},"n185972164":{"id":"n185972164","loc":[-85.616714,41.970839]},"n185972166":{"id":"n185972166","loc":[-85.615879,41.971969]},"n185972168":{"id":"n185972168","loc":[-85.615748,41.972159]},"n185972170":{"id":"n185972170","loc":[-85.615589,41.972502]},"n185972172":{"id":"n185972172","loc":[-85.615542,41.972733]},"n185972175":{"id":"n185972175","loc":[-85.615524,41.972947]},"n185972177":{"id":"n185972177","loc":[-85.615512,41.973715]},"n185972179":{"id":"n185972179","loc":[-85.615513,41.976496]},"n185972180":{"id":"n185972180","loc":[-85.615538,41.977246]},"n185972181":{"id":"n185972181","loc":[-85.61558,41.982139]},"n185972184":{"id":"n185972184","loc":[-85.61557,41.983317]},"n185972186":{"id":"n185972186","loc":[-85.615591,41.983463]},"n185972188":{"id":"n185972188","loc":[-85.615763,41.984146]},"n185972190":{"id":"n185972190","loc":[-85.615814,41.98435]},"n185972192":{"id":"n185972192","loc":[-85.615965,41.998453]},"n185972194":{"id":"n185972194","loc":[-85.615982,42.001237]},"n185972195":{"id":"n185972195","loc":[-85.616055,42.00555]},"n185972197":{"id":"n185972197","loc":[-85.616134,42.014887]},"n185972199":{"id":"n185972199","loc":[-85.616177,42.018465]},"n185972201":{"id":"n185972201","loc":[-85.616298,42.027627]},"n185972203":{"id":"n185972203","loc":[-85.616513,42.042212]},"w203968015":{"id":"w203968015","tags":{"highway":"residential"},"nodes":["n2139795768","n2139795769"]},"w17965932":{"id":"w17965932","tags":{"highway":"residential","name":"Buckhorn Road","name_1":"County Highway 122"},"nodes":["n185972155","n185972156","n185972157","n185972158","n185972159","n185972160","n185969070","n185972161","n185972162","n185972164","n185972166","n185972168","n185969040","n185972170","n185972172","n185972175","n185972177","n185972179","n185966614","n185972180","n185972181","n185972184","n185972186","n185963539","n185972188","n185972190","n185972192","n185972194","n185972195","n185966635","n185972197","n185972199","n185972201","n185972203","n185964418"]},"w203968016":{"id":"w203968016","tags":{"highway":"residential","name":"New Jersey Court"},"nodes":["n2139795770","n2139795771","n2139795772","n2139795773","n2139795774","n2139795775","n2139795776","n2139795777","n2139795770","n2139795778","n2139795779","n2139795769"]},"w203968017":{"id":"w203968017","tags":{"highway":"residential","name":"Oklahoma Drive"},"nodes":["n2139795780","n2139795781","n2139795782","n2139795783","n2139795769"]},"n1819790528":{"id":"n1819790528","loc":[-85.6184827,41.960025]},"n1819790530":{"id":"n1819790530","loc":[-85.6168626,41.9605834]},"n1819790534":{"id":"n1819790534","loc":[-85.6197379,41.9617163]},"n1819790541":{"id":"n1819790541","loc":[-85.6198881,41.9620833]},"n1819790543":{"id":"n1819790543","loc":[-85.619695,41.9619397]},"n1819790547":{"id":"n1819790547","loc":[-85.6190298,41.9609504]},"n1819790555":{"id":"n1819790555","loc":[-85.6180471,41.9609788]},"n1819790559":{"id":"n1819790559","loc":[-85.6203817,41.9605436]},"n1819790583":{"id":"n1819790583","loc":[-85.6201564,41.9603282]},"n1819790590":{"id":"n1819790590","loc":[-85.617045,41.9598894]},"n1819790609":{"id":"n1819790609","loc":[-85.6177638,41.9598495]},"n1819790618":{"id":"n1819790618","loc":[-85.6195234,41.9610143]},"n1819790642":{"id":"n1819790642","loc":[-85.6181179,41.9627933]},"n1819790659":{"id":"n1819790659","loc":[-85.6174634,41.962897]},"n1819790665":{"id":"n1819790665","loc":[-85.6170343,41.9630885]},"n1819790674":{"id":"n1819790674","loc":[-85.6194697,41.9601925]},"n1819790685":{"id":"n1819790685","loc":[-85.6207722,41.9610665]},"n1819790687":{"id":"n1819790687","loc":[-85.6202315,41.9622109]},"n1819790697":{"id":"n1819790697","loc":[-85.6184505,41.9624662]},"n1819790726":{"id":"n1819790726","loc":[-85.6178926,41.9628492]},"n1819790738":{"id":"n1819790738","loc":[-85.6173347,41.9598016]},"n1819790762":{"id":"n1819790762","loc":[-85.6186221,41.9609105]},"n1819790774":{"id":"n1819790774","loc":[-85.6175922,41.9608308]},"n1819790781":{"id":"n1819790781","loc":[-85.6167768,41.9633198]},"n1819790796":{"id":"n1819790796","loc":[-85.619856,41.961461]},"n1819790811":{"id":"n1819790811","loc":[-85.6208215,41.9620195]},"n1819790833":{"id":"n1819790833","loc":[-85.618311,41.9612536]},"n1819790854":{"id":"n1819790854","loc":[-85.6183646,41.9626417]},"n1819790863":{"id":"n1819790863","loc":[-85.6204997,41.9608547]},"n1819790867":{"id":"n1819790867","loc":[-85.6184934,41.9621391]},"n1819790877":{"id":"n1819790877","loc":[-85.6206928,41.9621152]},"n1819790881":{"id":"n1819790881","loc":[-85.6170879,41.960735]},"n1819790891":{"id":"n1819790891","loc":[-85.6168304,41.9601207]},"n1819790898":{"id":"n1819790898","loc":[-85.619813,41.9612297]},"n1819790909":{"id":"n1819790909","loc":[-85.6167982,41.960376]},"n1819790912":{"id":"n1819790912","loc":[-85.6205855,41.9610462]},"n1819790544":{"id":"n1819790544","loc":[-85.612968,41.9707781]},"n1819790549":{"id":"n1819790549","loc":[-85.614395,41.9697172]},"n1819790552":{"id":"n1819790552","loc":[-85.6180535,41.9655536]},"n1819790554":{"id":"n1819790554","loc":[-85.6111227,41.9703713]},"n1819790560":{"id":"n1819790560","loc":[-85.6112729,41.9701958]},"n1819790563":{"id":"n1819790563","loc":[-85.6137512,41.9689917]},"n1819790564":{"id":"n1819790564","loc":[-85.6181072,41.9659205]},"n1819790595":{"id":"n1819790595","loc":[-85.6170021,41.9666863]},"n1819790605":{"id":"n1819790605","loc":[-85.6168948,41.9644527]},"n1819790606":{"id":"n1819790606","loc":[-85.6128071,41.9701081]},"n1819790607":{"id":"n1819790607","loc":[-85.6129251,41.9704032]},"n1819790612":{"id":"n1819790612","loc":[-85.6177638,41.9663912]},"n1819790615":{"id":"n1819790615","loc":[-85.6152533,41.9670373]},"n1819790622":{"id":"n1819790622","loc":[-85.6146739,41.9673804]},"n1819790623":{"id":"n1819790623","loc":[-85.6180428,41.9661838]},"n1819790625":{"id":"n1819790625","loc":[-85.6172918,41.9646202]},"n1819790645":{"id":"n1819790645","loc":[-85.6178067,41.965043]},"n1819790647":{"id":"n1819790647","loc":[-85.6143306,41.9712488]},"n1819790649":{"id":"n1819790649","loc":[-85.6147383,41.9707702]},"n1819790654":{"id":"n1819790654","loc":[-85.6157361,41.9668459]},"n1819790657":{"id":"n1819790657","loc":[-85.6145666,41.9710733]},"n1819790668":{"id":"n1819790668","loc":[-85.6166909,41.9642692]},"n1819790671":{"id":"n1819790671","loc":[-85.6141482,41.9696538]},"n1819790679":{"id":"n1819790679","loc":[-85.6148349,41.9705388]},"n1819790686":{"id":"n1819790686","loc":[-85.6139551,41.9695501]},"n1819790696":{"id":"n1819790696","loc":[-85.6119703,41.9699087]},"n1819790704":{"id":"n1819790704","loc":[-85.6140731,41.9684174]},"n1819790706":{"id":"n1819790706","loc":[-85.6124745,41.9699246]},"n1819790718":{"id":"n1819790718","loc":[-85.6165407,41.9636868]},"n1819790720":{"id":"n1819790720","loc":[-85.61388,41.9687365]},"n1819790731":{"id":"n1819790731","loc":[-85.6165193,41.9639421]},"n1819790739":{"id":"n1819790739","loc":[-85.6146739,41.9699964]},"n1819790753":{"id":"n1819790753","loc":[-85.6173883,41.9665747]},"n1819790760":{"id":"n1819790760","loc":[-85.6133221,41.9712089]},"n1819790767":{"id":"n1819790767","loc":[-85.6116698,41.9699246]},"n1819790779":{"id":"n1819790779","loc":[-85.6130753,41.9710573]},"n1819790791":{"id":"n1819790791","loc":[-85.6137083,41.9692869]},"n1819790795":{"id":"n1819790795","loc":[-85.6141482,41.9679627]},"n1819790798":{"id":"n1819790798","loc":[-85.6137727,41.9694305]},"n1819790836":{"id":"n1819790836","loc":[-85.6143842,41.9676037]},"n1819790915":{"id":"n1819790915","loc":[-85.6148456,41.9702756]},"n1819790926":{"id":"n1819790926","loc":[-85.6138371,41.9713525]},"n1819790927":{"id":"n1819790927","loc":[-85.6141053,41.9713525]},"n1819790931":{"id":"n1819790931","loc":[-85.6162832,41.966814]},"n1821014625":{"id":"n1821014625","loc":[-85.5960611,41.9808498]},"n1821014627":{"id":"n1821014627","loc":[-85.5565843,42.010982]},"n1821014629":{"id":"n1821014629","loc":[-85.5971541,41.9805808]},"n1821014632":{"id":"n1821014632","loc":[-85.6061837,41.9725907]},"n1821014633":{"id":"n1821014633","loc":[-85.5247773,42.025766]},"n1821014635":{"id":"n1821014635","loc":[-85.5908938,41.9902384]},"n1821014636":{"id":"n1821014636","loc":[-85.5917682,41.9860637]},"n1821014637":{"id":"n1821014637","loc":[-85.5456556,42.0166797]},"n1821014638":{"id":"n1821014638","loc":[-85.5795749,42.0032352]},"n1821014639":{"id":"n1821014639","loc":[-85.6103988,41.9723456]},"n1821014642":{"id":"n1821014642","loc":[-85.5818816,42.0022466]},"n1821014643":{"id":"n1821014643","loc":[-85.5570604,42.0091586]},"n1821014644":{"id":"n1821014644","loc":[-85.5952886,41.9803792]},"n1821014645":{"id":"n1821014645","loc":[-85.5780366,42.0040343]},"n1821014646":{"id":"n1821014646","loc":[-85.6050505,41.9751971]},"n1821014647":{"id":"n1821014647","loc":[-85.5854435,41.9946162]},"n1821014648":{"id":"n1821014648","loc":[-85.5452278,42.0168768]},"n1821014649":{"id":"n1821014649","loc":[-85.6023254,41.9780166]},"n1821014651":{"id":"n1821014651","loc":[-85.5761899,42.0046783]},"n1821014653":{"id":"n1821014653","loc":[-85.5897351,41.9876707]},"n1821014657":{"id":"n1821014657","loc":[-85.5963601,41.9808998]},"n1821014658":{"id":"n1821014658","loc":[-85.5892952,41.9951983]},"n1821014660":{"id":"n1821014660","loc":[-85.5778328,42.0037194]},"n1821014661":{"id":"n1821014661","loc":[-85.5541475,42.0125705]},"n1821014663":{"id":"n1821014663","loc":[-85.5914047,41.9856469]},"n1821014664":{"id":"n1821014664","loc":[-85.6101681,41.9727723]},"n1821014665":{"id":"n1821014665","loc":[-85.5910172,41.9854696]},"n1821014666":{"id":"n1821014666","loc":[-85.5398688,42.0187699]},"n1821014667":{"id":"n1821014667","loc":[-85.5218752,42.0282884]},"n1821014668":{"id":"n1821014668","loc":[-85.5159582,42.0329384]},"n1821014669":{"id":"n1821014669","loc":[-85.5898102,41.9847319]},"n1821014670":{"id":"n1821014670","loc":[-85.5734809,42.0066235]},"n1821014671":{"id":"n1821014671","loc":[-85.5922939,41.980852]},"n1821014672":{"id":"n1821014672","loc":[-85.6023629,41.9781163]},"n1821014674":{"id":"n1821014674","loc":[-85.5409953,42.0191724]},"n1821014676":{"id":"n1821014676","loc":[-85.584435,41.9949909]},"n1821014677":{"id":"n1821014677","loc":[-85.5972399,41.9783835]},"n1821014678":{"id":"n1821014678","loc":[-85.5616738,42.0071337]},"n1821014681":{"id":"n1821014681","loc":[-85.5202994,42.0310755]},"n1821014682":{"id":"n1821014682","loc":[-85.5915912,41.9857767]},"n1821014684":{"id":"n1821014684","loc":[-85.6022288,41.977897]},"n1821014687":{"id":"n1821014687","loc":[-85.5933024,41.9846362]},"n1821014688":{"id":"n1821014688","loc":[-85.5846871,41.9956169]},"n1821014689":{"id":"n1821014689","loc":[-85.5898209,41.99037]},"n1821014691":{"id":"n1821014691","loc":[-85.5448939,42.0149261]},"n1821014692":{"id":"n1821014692","loc":[-85.5977763,41.9786348]},"n1821014694":{"id":"n1821014694","loc":[-85.5767706,42.0034523]},"n1821014695":{"id":"n1821014695","loc":[-85.6103559,41.9726766]},"n1821014697":{"id":"n1821014697","loc":[-85.5922134,41.9809876]},"n1821014698":{"id":"n1821014698","loc":[-85.5935277,41.9831728]},"n1821014700":{"id":"n1821014700","loc":[-85.5674674,42.0078273]},"n1821014703":{"id":"n1821014703","loc":[-85.6021,41.9778053]},"n1821014704":{"id":"n1821014704","loc":[-85.5756763,42.0053737]},"n1821014705":{"id":"n1821014705","loc":[-85.5887695,41.9895207]},"n1821014707":{"id":"n1821014707","loc":[-85.6061073,41.9746866]},"n1821014708":{"id":"n1821014708","loc":[-85.6033446,41.9751692]},"n1821014710":{"id":"n1821014710","loc":[-85.5180986,42.0322332]},"n1821014711":{"id":"n1821014711","loc":[-85.543365,42.0163569]},"n1821014712":{"id":"n1821014712","loc":[-85.6030656,41.9753646]},"n1821014713":{"id":"n1821014713","loc":[-85.6104417,41.9704792]},"n1821014714":{"id":"n1821014714","loc":[-85.5205716,42.030998]},"n1821014716":{"id":"n1821014716","loc":[-85.516382,42.032536]},"n1821014717":{"id":"n1821014717","loc":[-85.5932863,41.9820882]},"n1821014718":{"id":"n1821014718","loc":[-85.5361928,42.0194974]},"n1821014720":{"id":"n1821014720","loc":[-85.6011613,41.9773586]},"n1821014721":{"id":"n1821014721","loc":[-85.554287,42.0109124]},"n1821014722":{"id":"n1821014722","loc":[-85.5577524,42.0103425]},"n1821014725":{"id":"n1821014725","loc":[-85.5867256,41.9921004]},"n1821014726":{"id":"n1821014726","loc":[-85.5856045,41.9968807]},"n1821014727":{"id":"n1821014727","loc":[-85.5545445,42.0106454]},"n1821014728":{"id":"n1821014728","loc":[-85.5923797,41.9842534]},"n1821014729":{"id":"n1821014729","loc":[-85.5696346,42.0081462]},"n1821014730":{"id":"n1821014730","loc":[-85.5998322,41.9786884]},"n1821014735":{"id":"n1821014735","loc":[-85.5337426,42.0218266]},"n1821014736":{"id":"n1821014736","loc":[-85.5847944,41.994672]},"n1821014740":{"id":"n1821014740","loc":[-85.5315271,42.0238669]},"n1821014741":{"id":"n1821014741","loc":[-85.5248846,42.027085]},"n1821014742":{"id":"n1821014742","loc":[-85.5853376,41.997018]},"n1821014743":{"id":"n1821014743","loc":[-85.5894883,41.988811]},"n1821014745":{"id":"n1821014745","loc":[-85.6095311,41.9726226]},"n1821014746":{"id":"n1821014746","loc":[-85.5531511,42.0133416]},"n1821014747":{"id":"n1821014747","loc":[-85.5735882,42.007058]},"n1821014749":{"id":"n1821014749","loc":[-85.5428554,42.0164366]},"n1821014751":{"id":"n1821014751","loc":[-85.5395255,42.0186304]},"n1821014752":{"id":"n1821014752","loc":[-85.571378,42.0083176]},"n1821014754":{"id":"n1821014754","loc":[-85.5541918,42.0113925]},"n1821014755":{"id":"n1821014755","loc":[-85.5278029,42.0250806]},"n1821014756":{"id":"n1821014756","loc":[-85.5936725,41.9827102]},"n1821014757":{"id":"n1821014757","loc":[-85.5176266,42.0346677]},"n1821014758":{"id":"n1821014758","loc":[-85.6096692,41.9714245]},"n1821014759":{"id":"n1821014759","loc":[-85.5770321,42.0034266]},"n1821014761":{"id":"n1821014761","loc":[-85.5988921,41.9779369]},"n1821014762":{"id":"n1821014762","loc":[-85.5811788,42.0024499]},"n1821014763":{"id":"n1821014763","loc":[-85.5154003,42.0381101]},"n1821014764":{"id":"n1821014764","loc":[-85.5155827,42.0374089]},"n1821014765":{"id":"n1821014765","loc":[-85.5891249,41.9884978]},"n1821014766":{"id":"n1821014766","loc":[-85.5313863,42.0238293]},"n1821014768":{"id":"n1821014768","loc":[-85.593297,41.9833363]},"n1821014769":{"id":"n1821014769","loc":[-85.5849446,41.9957245]},"n1821014770":{"id":"n1821014770","loc":[-85.5537774,42.0130847]},"n1821014771":{"id":"n1821014771","loc":[-85.6111766,41.9706069]},"n1821014772":{"id":"n1821014772","loc":[-85.5585477,42.008989]},"n1821014774":{"id":"n1821014774","loc":[-85.5928142,41.9852623]},"n1821014777":{"id":"n1821014777","loc":[-85.5891933,41.9882608]},"n1821014778":{"id":"n1821014778","loc":[-85.5926909,41.9817532]},"n1821014779":{"id":"n1821014779","loc":[-85.5260272,42.0252201]},"n1821014781":{"id":"n1821014781","loc":[-85.5894615,41.9950468]},"n1821014782":{"id":"n1821014782","loc":[-85.5461063,42.0143242]},"n1821014783":{"id":"n1821014783","loc":[-85.5711527,42.0085886]},"n1821014784":{"id":"n1821014784","loc":[-85.5329379,42.0218624]},"n1821014786":{"id":"n1821014786","loc":[-85.583047,42.0020252]},"n1821014787":{"id":"n1821014787","loc":[-85.5758962,42.0054095]},"n1821014788":{"id":"n1821014788","loc":[-85.5626354,42.0077733]},"n1821014789":{"id":"n1821014789","loc":[-85.6029852,41.9755999]},"n1821014790":{"id":"n1821014790","loc":[-85.5892362,41.9886755]},"n1821014791":{"id":"n1821014791","loc":[-85.5157597,42.0372017]},"n1821014793":{"id":"n1821014793","loc":[-85.6054582,41.9751094]},"n1821014794":{"id":"n1821014794","loc":[-85.5986936,41.9778412]},"n1821014795":{"id":"n1821014795","loc":[-85.5880775,41.98976]},"n1821014796":{"id":"n1821014796","loc":[-85.5858727,41.9963624]},"n1821014798":{"id":"n1821014798","loc":[-85.5792543,42.0035958]},"n1821014799":{"id":"n1821014799","loc":[-85.5921665,41.9838326]},"n1821014801":{"id":"n1821014801","loc":[-85.599214,41.9782599]},"n1821014802":{"id":"n1821014802","loc":[-85.5571905,42.0090967]},"n1821014803":{"id":"n1821014803","loc":[-85.5426891,42.0173612]},"n1821014804":{"id":"n1821014804","loc":[-85.5889626,41.9896404]},"n1821014805":{"id":"n1821014805","loc":[-85.5491264,42.0141648]},"n1821014806":{"id":"n1821014806","loc":[-85.5618897,42.0072631]},"n1821014808":{"id":"n1821014808","loc":[-85.5573501,42.0109802]},"n1821014809":{"id":"n1821014809","loc":[-85.5983463,41.9778031]},"n1821014810":{"id":"n1821014810","loc":[-85.5885173,41.9895128]},"n1821014811":{"id":"n1821014811","loc":[-85.6084998,41.9721143]},"n1821014812":{"id":"n1821014812","loc":[-85.5737598,42.0056389]},"n1821014814":{"id":"n1821014814","loc":[-85.5542173,42.0118132]},"n1821014816":{"id":"n1821014816","loc":[-85.5277868,42.024451]},"n1821014817":{"id":"n1821014817","loc":[-85.5403999,42.0191724]},"n1821014819":{"id":"n1821014819","loc":[-85.5983879,41.9791452]},"n1821014820":{"id":"n1821014820","loc":[-85.5891302,41.9897578]},"n1821014822":{"id":"n1821014822","loc":[-85.5930731,41.9805108]},"n1821014824":{"id":"n1821014824","loc":[-85.515395,42.0378471]},"n1821014825":{"id":"n1821014825","loc":[-85.5352755,42.0205136]},"n1821014826":{"id":"n1821014826","loc":[-85.5502744,42.0133398]},"n1821014828":{"id":"n1821014828","loc":[-85.5701295,42.0088256]},"n1821014830":{"id":"n1821014830","loc":[-85.5888929,41.9953099]},"n1821014832":{"id":"n1821014832","loc":[-85.5880077,41.9901547]},"n1821014833":{"id":"n1821014833","loc":[-85.5451192,42.0157072]},"n1821014834":{"id":"n1821014834","loc":[-85.6096478,41.9711932]},"n1821014835":{"id":"n1821014835","loc":[-85.5806424,42.0026532]},"n1821014836":{"id":"n1821014836","loc":[-85.5911674,41.9868732]},"n1821014838":{"id":"n1821014838","loc":[-85.5930302,41.9836571]},"n1821014839":{"id":"n1821014839","loc":[-85.588925,41.9938148]},"n1821014840":{"id":"n1821014840","loc":[-85.6111874,41.9705311]},"n1821014841":{"id":"n1821014841","loc":[-85.5680843,42.0075842]},"n1821014842":{"id":"n1821014842","loc":[-85.6012793,41.9775062]},"n1821014843":{"id":"n1821014843","loc":[-85.5855562,41.9989777]},"n1821014844":{"id":"n1821014844","loc":[-85.5506137,42.0131662]},"n1821014845":{"id":"n1821014845","loc":[-85.5270049,42.025457]},"n1821014846":{"id":"n1821014846","loc":[-85.5257054,42.025244]},"n1821014847":{"id":"n1821014847","loc":[-85.6011184,41.9771832]},"n1821014848":{"id":"n1821014848","loc":[-85.515534,42.0389234]},"n1821014850":{"id":"n1821014850","loc":[-85.5847032,42.0010347]},"n1821014853":{"id":"n1821014853","loc":[-85.5361499,42.019063]},"n1821014854":{"id":"n1821014854","loc":[-85.5439176,42.0165721]},"n1821014855":{"id":"n1821014855","loc":[-85.5838825,42.0017284]},"n1821014857":{"id":"n1821014857","loc":[-85.5542173,42.0122317]},"n1821014859":{"id":"n1821014859","loc":[-85.5708201,42.0089195]},"n1821014860":{"id":"n1821014860","loc":[-85.5844833,41.9954415]},"n1821014862":{"id":"n1821014862","loc":[-85.5223204,42.0295396]},"n1821014863":{"id":"n1821014863","loc":[-85.5777898,42.0035918]},"n1821014864":{"id":"n1821014864","loc":[-85.591044,41.9898078]},"n1821014865":{"id":"n1821014865","loc":[-85.5973204,41.980182]},"n1821014866":{"id":"n1821014866","loc":[-85.5699578,42.0085825]},"n1821014867":{"id":"n1821014867","loc":[-85.5210598,42.0305278]},"n1821014868":{"id":"n1821014868","loc":[-85.5929108,41.9819008]},"n1821014869":{"id":"n1821014869","loc":[-85.5279799,42.0242995]},"n1821014870":{"id":"n1821014870","loc":[-85.5196114,42.0320539]},"n1821014871":{"id":"n1821014871","loc":[-85.5785449,42.0040883]},"n1821014872":{"id":"n1821014872","loc":[-85.588292,41.9895766]},"n1821014873":{"id":"n1821014873","loc":[-85.5160172,42.0331775]},"n1821014874":{"id":"n1821014874","loc":[-85.5688849,42.0077016]},"n1821014876":{"id":"n1821014876","loc":[-85.5857976,41.9996036]},"n1821014879":{"id":"n1821014879","loc":[-85.5990906,41.9780765]},"n1821014881":{"id":"n1821014881","loc":[-85.5483647,42.0144279]},"n1821014883":{"id":"n1821014883","loc":[-85.5691209,42.0077972]},"n1821014885":{"id":"n1821014885","loc":[-85.6076844,41.9721103]},"n1821014886":{"id":"n1821014886","loc":[-85.6015489,41.9766147]},"n1821014887":{"id":"n1821014887","loc":[-85.574822,42.0052802]},"n1821014888":{"id":"n1821014888","loc":[-85.5880024,41.9899593]},"n1821014890":{"id":"n1821014890","loc":[-85.5909421,41.9893772]},"n1821014892":{"id":"n1821014892","loc":[-85.5497326,42.0138141]},"n1821014893":{"id":"n1821014893","loc":[-85.5167106,42.0357811]},"n1821014895":{"id":"n1821014895","loc":[-85.5844404,41.9952501]},"n1821014896":{"id":"n1821014896","loc":[-85.5362465,42.0192662]},"n1821014898":{"id":"n1821014898","loc":[-85.5906095,41.9889147]},"n1821014899":{"id":"n1821014899","loc":[-85.5590667,42.0089354]},"n1821014900":{"id":"n1821014900","loc":[-85.5921598,41.9844209]},"n1821014902":{"id":"n1821014902","loc":[-85.5778971,42.0039266]},"n1821014903":{"id":"n1821014903","loc":[-85.603012,41.9761981]},"n1821014904":{"id":"n1821014904","loc":[-85.6108977,41.9706787]},"n1821014905":{"id":"n1821014905","loc":[-85.5685738,42.0076139]},"n1821014906":{"id":"n1821014906","loc":[-85.5392787,42.0186304]},"n1821014907":{"id":"n1821014907","loc":[-85.5227885,42.0274972]},"n1821014908":{"id":"n1821014908","loc":[-85.5857547,41.9961431]},"n1821014910":{"id":"n1821014910","loc":[-85.5610354,42.0072812]},"n1821014911":{"id":"n1821014911","loc":[-85.5209632,42.0308705]},"n1821014912":{"id":"n1821014912","loc":[-85.5709757,42.0087959]},"n1821014913":{"id":"n1821014913","loc":[-85.59231,41.9839344]},"n1821014914":{"id":"n1821014914","loc":[-85.5375245,42.0185865]},"n1821014916":{"id":"n1821014916","loc":[-85.5901548,41.9839841]},"n1821014917":{"id":"n1821014917","loc":[-85.5611213,42.0086405]},"n1821014918":{"id":"n1821014918","loc":[-85.5360426,42.0198122]},"n1821014919":{"id":"n1821014919","loc":[-85.5862817,41.9948691]},"n1821014921":{"id":"n1821014921","loc":[-85.5469807,42.0144438]},"n1821014922":{"id":"n1821014922","loc":[-85.5761309,42.0053838]},"n1821014924":{"id":"n1821014924","loc":[-85.516264,42.0332971]},"n1821014925":{"id":"n1821014925","loc":[-85.5277224,42.0246661]},"n1821014926":{"id":"n1821014926","loc":[-85.5980016,41.9798231]},"n1821014928":{"id":"n1821014928","loc":[-85.5924548,41.9806965]},"n1821014930":{"id":"n1821014930","loc":[-85.5899121,41.985023]},"n1821014931":{"id":"n1821014931","loc":[-85.5706015,42.0089492]},"n1821014932":{"id":"n1821014932","loc":[-85.515926,42.033046]},"n1821014933":{"id":"n1821014933","loc":[-85.5982377,41.9796796]},"n1821014936":{"id":"n1821014936","loc":[-85.5475721,42.0145253]},"n1821014938":{"id":"n1821014938","loc":[-85.5895701,41.9902323]},"n1821014939":{"id":"n1821014939","loc":[-85.6030495,41.9759947]},"n1821014942":{"id":"n1821014942","loc":[-85.6094721,41.9724989]},"n1821014944":{"id":"n1821014944","loc":[-85.5921973,41.9811112]},"n1821014945":{"id":"n1821014945","loc":[-85.5223526,42.0291332]},"n1821014946":{"id":"n1821014946","loc":[-85.5965103,41.9808998]},"n1821014948":{"id":"n1821014948","loc":[-85.517766,42.0349227]},"n1821014950":{"id":"n1821014950","loc":[-85.5889894,41.990996]},"n1821014951":{"id":"n1821014951","loc":[-85.5601932,42.0092902]},"n1821014954":{"id":"n1821014954","loc":[-85.6028135,41.9764055]},"n1821014955":{"id":"n1821014955","loc":[-85.5520621,42.0130666]},"n1821014956":{"id":"n1821014956","loc":[-85.593002,41.9839344]},"n1821014957":{"id":"n1821014957","loc":[-85.515926,42.0369666]},"n1821014960":{"id":"n1821014960","loc":[-85.5761255,42.003877]},"n1821014961":{"id":"n1821014961","loc":[-85.5716355,42.007911]},"n1821014962":{"id":"n1821014962","loc":[-85.5575378,42.0109045]},"n1821014963":{"id":"n1821014963","loc":[-85.5735667,42.0068188]},"n1821014964":{"id":"n1821014964","loc":[-85.5915214,41.9865861]},"n1821014965":{"id":"n1821014965","loc":[-85.5866344,41.9923157]},"n1821014967":{"id":"n1821014967","loc":[-85.5283138,42.0242256]},"n1821014968":{"id":"n1821014968","loc":[-85.5177875,42.0355801]},"n1821014969":{"id":"n1821014969","loc":[-85.548071,42.0144934]},"n1821014972":{"id":"n1821014972","loc":[-85.5611159,42.0088557]},"n1821014973":{"id":"n1821014973","loc":[-85.541686,42.0188757]},"n1821014974":{"id":"n1821014974","loc":[-85.5917628,41.9862631]},"n1821014975":{"id":"n1821014975","loc":[-85.5854864,41.9959478]},"n1821014977":{"id":"n1821014977","loc":[-85.609102,41.9722317]},"n1821014980":{"id":"n1821014980","loc":[-85.5761202,42.0042438]},"n1821014982":{"id":"n1821014982","loc":[-85.5465944,42.0143601]},"n1821014983":{"id":"n1821014983","loc":[-85.5173261,42.0342732]},"n1821014984":{"id":"n1821014984","loc":[-85.5897297,41.9888509]},"n1821014985":{"id":"n1821014985","loc":[-85.5856688,41.999181]},"n1821014986":{"id":"n1821014986","loc":[-85.5344011,42.0217251]},"n1821014987":{"id":"n1821014987","loc":[-85.601467,41.9768203]},"n1821014988":{"id":"n1821014988","loc":[-85.5457254,42.0165123]},"n1821014989":{"id":"n1821014989","loc":[-85.6023482,41.9784332]},"n1821014991":{"id":"n1821014991","loc":[-85.5361606,42.01823]},"n1821014992":{"id":"n1821014992","loc":[-85.5178465,42.0351139]},"n1821014995":{"id":"n1821014995","loc":[-85.5634293,42.0078092]},"n1821014996":{"id":"n1821014996","loc":[-85.573497,42.0072015]},"n1821014997":{"id":"n1821014997","loc":[-85.5976328,41.9799725]},"n1821014998":{"id":"n1821014998","loc":[-85.5210651,42.0303166]},"n1821015003":{"id":"n1821015003","loc":[-85.5222131,42.0288064]},"n1821015004":{"id":"n1821015004","loc":[-85.5897941,41.984405]},"n1821015005":{"id":"n1821015005","loc":[-85.5975725,41.9776099]},"n1821015006":{"id":"n1821015006","loc":[-85.5765708,42.0034903]},"n1821015007":{"id":"n1821015007","loc":[-85.5250187,42.026559]},"n1821015009":{"id":"n1821015009","loc":[-85.5426998,42.0166279]},"n1821015010":{"id":"n1821015010","loc":[-85.5957606,41.9806584]},"n1821015011":{"id":"n1821015011","loc":[-85.5262753,42.0252497]},"n1821015012":{"id":"n1821015012","loc":[-85.5266455,42.0253374]},"n1821015014":{"id":"n1821015014","loc":[-85.5515632,42.0130187]},"n1821015015":{"id":"n1821015015","loc":[-85.6024058,41.9765212]},"n1821015017":{"id":"n1821015017","loc":[-85.5175032,42.0357156]},"n1821015018":{"id":"n1821015018","loc":[-85.5302718,42.0236039]},"n1821015019":{"id":"n1821015019","loc":[-85.6024005,41.9782759]},"n1821015020":{"id":"n1821015020","loc":[-85.5907758,41.9890821]},"n1821015021":{"id":"n1821015021","loc":[-85.6019445,41.9777215]},"n1821015022":{"id":"n1821015022","loc":[-85.5942854,41.9800881]},"n1821015024":{"id":"n1821015024","loc":[-85.5325826,42.0222711]},"n1821015029":{"id":"n1821015029","loc":[-85.555093,42.0105316]},"n1821015033":{"id":"n1821015033","loc":[-85.5249704,42.0270372]},"n1821015034":{"id":"n1821015034","loc":[-85.5243965,42.0272205]},"n1821015038":{"id":"n1821015038","loc":[-85.5413426,42.0190749]},"n1821015039":{"id":"n1821015039","loc":[-85.5920431,41.9848175]},"n1821015041":{"id":"n1821015041","loc":[-85.5577685,42.0106015]},"n1821015042":{"id":"n1821015042","loc":[-85.5453606,42.0158866]},"n1821015045":{"id":"n1821015045","loc":[-85.5333228,42.0217889]},"n1821015046":{"id":"n1821015046","loc":[-85.5426891,42.0175924]},"n1821015048":{"id":"n1821015048","loc":[-85.5886836,41.9936474]},"n1821015050":{"id":"n1821015050","loc":[-85.6001152,41.9786467]},"n1821015051":{"id":"n1821015051","loc":[-85.6094064,41.9723655]},"n1821015053":{"id":"n1821015053","loc":[-85.605721,41.9749738]},"n1821015055":{"id":"n1821015055","loc":[-85.6106791,41.9705048]},"n1821015057":{"id":"n1821015057","loc":[-85.5210437,42.0307071]},"n1821015059":{"id":"n1821015059","loc":[-85.5995694,41.9786725]},"n1821015060":{"id":"n1821015060","loc":[-85.5371638,42.0182938]},"n1821015062":{"id":"n1821015062","loc":[-85.6111766,41.9704593]},"n1821015065":{"id":"n1821015065","loc":[-85.577704,42.0034921]},"n1821015067":{"id":"n1821015067","loc":[-85.5570067,42.0093699]},"n1821015068":{"id":"n1821015068","loc":[-85.5920364,41.9845525]},"n1821015069":{"id":"n1821015069","loc":[-85.5252065,42.0253954]},"n1821015072":{"id":"n1821015072","loc":[-85.5664159,42.0088517]},"n1821015073":{"id":"n1821015073","loc":[-85.5880399,41.991905]},"n1821015075":{"id":"n1821015075","loc":[-85.6099871,41.9727861]},"n1821015076":{"id":"n1821015076","loc":[-85.5319603,42.0231478]},"n1821015078":{"id":"n1821015078","loc":[-85.6036088,41.9751112]},"n1821015080":{"id":"n1821015080","loc":[-85.5983128,41.9789179]},"n1821015082":{"id":"n1821015082","loc":[-85.5614069,42.0071395]},"n1821015083":{"id":"n1821015083","loc":[-85.60968,41.9709738]},"n1821015086":{"id":"n1821015086","loc":[-85.5914195,41.9837351]},"n1821015087":{"id":"n1821015087","loc":[-85.5895473,41.9948036]},"n1821015090":{"id":"n1821015090","loc":[-85.5929913,41.9851905]},"n1821015093":{"id":"n1821015093","loc":[-85.5907396,41.9838485]},"n1821015095":{"id":"n1821015095","loc":[-85.5893864,41.9880176]},"n1821015096":{"id":"n1821015096","loc":[-85.5788024,42.0039807]},"n1821015097":{"id":"n1821015097","loc":[-85.5630592,42.0078411]},"n1821015098":{"id":"n1821015098","loc":[-85.5350609,42.0211274]},"n1821015099":{"id":"n1821015099","loc":[-85.5967195,41.9808679]},"n1821015100":{"id":"n1821015100","loc":[-85.5666734,42.0088119]},"n1821015101":{"id":"n1821015101","loc":[-85.564694,42.0077675]},"n1821015103":{"id":"n1821015103","loc":[-85.6066544,41.9726527]},"n1821015104":{"id":"n1821015104","loc":[-85.6011827,41.9769838]},"n1821015105":{"id":"n1821015105","loc":[-85.5972131,41.9776697]},"n1821015106":{"id":"n1821015106","loc":[-85.5880828,41.9903341]},"n1821015107":{"id":"n1821015107","loc":[-85.5510268,42.0130626]},"n1821015108":{"id":"n1821015108","loc":[-85.6102164,41.970543]},"n1821015109":{"id":"n1821015109","loc":[-85.5905344,41.9853899]},"n1821015111":{"id":"n1821015111","loc":[-85.5888821,41.9913429]},"n1821015112":{"id":"n1821015112","loc":[-85.606295,41.9741921]},"n1821015114":{"id":"n1821015114","loc":[-85.5969556,41.9807443]},"n1821015115":{"id":"n1821015115","loc":[-85.5882223,41.9934081]},"n1821015116":{"id":"n1821015116","loc":[-85.6104471,41.9724971]},"n1821015118":{"id":"n1821015118","loc":[-85.5406091,42.0192162]},"n1821015120":{"id":"n1821015120","loc":[-85.589955,41.9888429]},"n1821015121":{"id":"n1821015121","loc":[-85.5598821,42.0092304]},"n1821015122":{"id":"n1821015122","loc":[-85.545598,42.0144097]},"n1821015123":{"id":"n1821015123","loc":[-85.5649528,42.0079965]},"n1821015125":{"id":"n1821015125","loc":[-85.5883993,41.9917814]},"n1821015126":{"id":"n1821015126","loc":[-85.5295785,42.0239967]},"n1821015129":{"id":"n1821015129","loc":[-85.5648723,42.0078809]},"n1821015132":{"id":"n1821015132","loc":[-85.564989,42.0081103]},"n1821015133":{"id":"n1821015133","loc":[-85.5946127,41.9800841]},"n1821015134":{"id":"n1821015134","loc":[-85.583448,42.0019078]},"n1821015135":{"id":"n1821015135","loc":[-85.5905934,41.9871842]},"n1821015137":{"id":"n1821015137","loc":[-85.610608,41.9704752]},"n1821015138":{"id":"n1821015138","loc":[-85.5752257,42.0052939]},"n1821015139":{"id":"n1821015139","loc":[-85.5893864,41.9943491]},"n1821015140":{"id":"n1821015140","loc":[-85.5426247,42.0169866]},"n1821015141":{"id":"n1821015141","loc":[-85.562001,42.0074526]},"n1821015142":{"id":"n1821015142","loc":[-85.5212046,42.0301094]},"n1821015143":{"id":"n1821015143","loc":[-85.602214,41.9784531]},"n1821015144":{"id":"n1821015144","loc":[-85.5858687,41.9948293]},"n1821015145":{"id":"n1821015145","loc":[-85.5608477,42.0074805]},"n1821015146":{"id":"n1821015146","loc":[-85.5651607,42.0083614]},"n1821015147":{"id":"n1821015147","loc":[-85.5288288,42.0242495]},"n1821015149":{"id":"n1821015149","loc":[-85.5450334,42.0146989]},"n1821015151":{"id":"n1821015151","loc":[-85.5578275,42.0092304]},"n1821015154":{"id":"n1821015154","loc":[-85.6056634,41.9724511]},"n1821015155":{"id":"n1821015155","loc":[-85.5902179,41.9852742]},"n1821015156":{"id":"n1821015156","loc":[-85.5156256,42.0387157]},"n1821015157":{"id":"n1821015157","loc":[-85.5734433,42.0059459]},"n1821015158":{"id":"n1821015158","loc":[-85.6050773,41.9731273]},"n1821015160":{"id":"n1821015160","loc":[-85.5223419,42.0275233]},"n1821015163":{"id":"n1821015163","loc":[-85.6053562,41.972525]},"n1821015164":{"id":"n1821015164","loc":[-85.5850412,41.9946082]},"n1821015165":{"id":"n1821015165","loc":[-85.5359031,42.0186326]},"n1821015166":{"id":"n1821015166","loc":[-85.5608745,42.0077635]},"n1821015169":{"id":"n1821015169","loc":[-85.572876,42.0073189]},"n1821015171":{"id":"n1821015171","loc":[-85.5875424,41.9919188]},"n1821015172":{"id":"n1821015172","loc":[-85.5240116,42.0272581]},"n1821015173":{"id":"n1821015173","loc":[-85.5318369,42.0236818]},"n1821015174":{"id":"n1821015174","loc":[-85.566888,42.0086923]},"n1821015175":{"id":"n1821015175","loc":[-85.5931522,41.9850669]},"n1821015176":{"id":"n1821015176","loc":[-85.5604842,42.0093199]},"n1821015177":{"id":"n1821015177","loc":[-85.5868168,41.9927543]},"n1821015178":{"id":"n1821015178","loc":[-85.6052275,41.9732549]},"n1821015179":{"id":"n1821015179","loc":[-85.5910118,41.9900431]},"n1821015182":{"id":"n1821015182","loc":[-85.5610032,42.0082897]},"n1821015183":{"id":"n1821015183","loc":[-85.5425443,42.0179431]},"n1821015184":{"id":"n1821015184","loc":[-85.5843277,42.0014055]},"n1821015186":{"id":"n1821015186","loc":[-85.5733307,42.0063564]},"n1821015188":{"id":"n1821015188","loc":[-85.5277385,42.0248694]},"n1821015189":{"id":"n1821015189","loc":[-85.5558427,42.0108168]},"n1821015190":{"id":"n1821015190","loc":[-85.5650587,42.0082618]},"n1821015191":{"id":"n1821015191","loc":[-85.5660351,42.0088278]},"n1821015192":{"id":"n1821015192","loc":[-85.5849768,41.9980049]},"n1821015194":{"id":"n1821015194","loc":[-85.5359139,42.0188199]},"n1821015195":{"id":"n1821015195","loc":[-85.593238,41.9849194]},"n1821015197":{"id":"n1821015197","loc":[-85.5850841,41.9983239]},"n1821015199":{"id":"n1821015199","loc":[-85.5983396,41.9794283]},"n1821015204":{"id":"n1821015204","loc":[-85.5452801,42.0145355]},"n1821015205":{"id":"n1821015205","loc":[-85.5340685,42.0218407]},"n1821015207":{"id":"n1821015207","loc":[-85.5773272,42.0034186]},"n1821015209":{"id":"n1821015209","loc":[-85.5535212,42.0132419]},"n1821015211":{"id":"n1821015211","loc":[-85.6107703,41.9706045]},"n1821015212":{"id":"n1821015212","loc":[-85.6030066,41.9758193]},"n1821015213":{"id":"n1821015213","loc":[-85.5359943,42.0184213]},"n1821015214":{"id":"n1821015214","loc":[-85.5922993,41.9813305]},"n1821015215":{"id":"n1821015215","loc":[-85.5672689,42.0080465]},"n1821015217":{"id":"n1821015217","loc":[-85.5160494,42.0365682]},"n1821015218":{"id":"n1821015218","loc":[-85.5401142,42.0190351]},"n1821015219":{"id":"n1821015219","loc":[-85.5607632,42.0092282]},"n1821015220":{"id":"n1821015220","loc":[-85.5866197,41.9947894]},"n1821015221":{"id":"n1821015221","loc":[-85.6017889,41.9765132]},"n1821015222":{"id":"n1821015222","loc":[-85.5595978,42.009059]},"n1821015226":{"id":"n1821015226","loc":[-85.5871494,41.9929018]},"n1821015227":{"id":"n1821015227","loc":[-85.5857708,41.9998866]},"n1821015228":{"id":"n1821015228","loc":[-85.5317135,42.0238094]},"n1821015231":{"id":"n1821015231","loc":[-85.5733521,42.0061372]},"n1821015233":{"id":"n1821015233","loc":[-85.5855991,42.0001936]},"n1821015234":{"id":"n1821015234","loc":[-85.5213924,42.029962]},"n1821015235":{"id":"n1821015235","loc":[-85.6052221,41.9726567]},"n1821015236":{"id":"n1821015236","loc":[-85.5763723,42.0035422]},"n1821015237":{"id":"n1821015237","loc":[-85.5858512,41.9966215]},"n1821015238":{"id":"n1821015238","loc":[-85.567061,42.008439]},"n1821015239":{"id":"n1821015239","loc":[-85.5250563,42.0269057]},"n1821015240":{"id":"n1821015240","loc":[-85.5347551,42.0214263]},"n1821015241":{"id":"n1821015241","loc":[-85.6098463,41.9707066]},"n1821015242":{"id":"n1821015242","loc":[-85.5676927,42.0076519]},"n1821015243":{"id":"n1821015243","loc":[-85.516775,42.0322669]},"n1821015244":{"id":"n1821015244","loc":[-85.5762275,42.0036538]},"n1821015245":{"id":"n1821015245","loc":[-85.5583639,42.0090949]},"n1821015246":{"id":"n1821015246","loc":[-85.5554041,42.0106432]},"n1821015247":{"id":"n1821015247","loc":[-85.5973364,41.9776099]},"n1821015248":{"id":"n1821015248","loc":[-85.6098945,41.9717513]},"n1821015249":{"id":"n1821015249","loc":[-85.6045315,41.9751511]},"n1821015250":{"id":"n1821015250","loc":[-85.5579938,42.0092264]},"n1821015253":{"id":"n1821015253","loc":[-85.6058873,41.9724652]},"n1821015254":{"id":"n1821015254","loc":[-85.5869456,41.9947517]},"n1821015255":{"id":"n1821015255","loc":[-85.5936565,41.9823713]},"n1821015256":{"id":"n1821015256","loc":[-85.5218269,42.0278102]},"n1821015258":{"id":"n1821015258","loc":[-85.5887802,41.9905534]},"n1821015259":{"id":"n1821015259","loc":[-85.5901924,41.9904515]},"n1821015263":{"id":"n1821015263","loc":[-85.5249222,42.0255787]},"n1821015265":{"id":"n1821015265","loc":[-85.5175206,42.0321672]},"n1821015266":{"id":"n1821015266","loc":[-85.5275722,42.0254034]},"n1821015267":{"id":"n1821015267","loc":[-85.6016226,41.9765451]},"n1821015269":{"id":"n1821015269","loc":[-85.5569316,42.011032]},"n1821015271":{"id":"n1821015271","loc":[-85.6010714,41.9785209]},"n1821015272":{"id":"n1821015272","loc":[-85.6050666,41.9729917]},"n1821015273":{"id":"n1821015273","loc":[-85.5891235,41.99529]},"n1821015274":{"id":"n1821015274","loc":[-85.515454,42.0376439]},"n1821015276":{"id":"n1821015276","loc":[-85.5776021,42.0034443]},"n1821015277":{"id":"n1821015277","loc":[-85.6041707,41.9751453]},"n1821015278":{"id":"n1821015278","loc":[-85.5444701,42.0167435]},"n1821015280":{"id":"n1821015280","loc":[-85.5923274,41.9852202]},"n1821015283":{"id":"n1821015283","loc":[-85.5893649,41.9900271]},"n1821015284":{"id":"n1821015284","loc":[-85.5933453,41.9804412]},"n1821015285":{"id":"n1821015285","loc":[-85.5247237,42.026017]},"n1821015286":{"id":"n1821015286","loc":[-85.5286182,42.0242477]},"n1821015287":{"id":"n1821015287","loc":[-85.5904003,41.9888549]},"n1821015288":{"id":"n1821015288","loc":[-85.6062146,41.9739369]},"n1821015290":{"id":"n1821015290","loc":[-85.5762596,42.0052602]},"n1821015292":{"id":"n1821015292","loc":[-85.5849715,41.9975465]},"n1821015293":{"id":"n1821015293","loc":[-85.585229,42.0006241]},"n1821015294":{"id":"n1821015294","loc":[-85.5926922,41.9805946]},"n1821015295":{"id":"n1821015295","loc":[-85.5703387,42.0089133]},"n1821015299":{"id":"n1821015299","loc":[-85.5789955,42.0038611]},"n1821015301":{"id":"n1821015301","loc":[-85.6072888,41.9721918]},"n1821015302":{"id":"n1821015302","loc":[-85.5356349,42.0200992]},"n1821015304":{"id":"n1821015304","loc":[-85.5891772,41.994066]},"n1821015306":{"id":"n1821015306","loc":[-85.606295,41.9744952]},"n1821015307":{"id":"n1821015307","loc":[-85.538871,42.0186583]},"n1821015308":{"id":"n1821015308","loc":[-85.587997,41.994971]},"n1821015311":{"id":"n1821015311","loc":[-85.606869,41.9725809]},"n1821015312":{"id":"n1821015312","loc":[-85.5171974,42.0339943]},"n1821015314":{"id":"n1821015314","loc":[-85.5327435,42.0220479]},"n1821015315":{"id":"n1821015315","loc":[-85.5383439,42.0187282]},"n1821015316":{"id":"n1821015316","loc":[-85.5248095,42.0263119]},"n1821015318":{"id":"n1821015318","loc":[-85.5732502,42.0073051]},"n1821015319":{"id":"n1821015319","loc":[-85.5924226,41.9852663]},"n1821015321":{"id":"n1821015321","loc":[-85.5179001,42.0353052]},"n1821015322":{"id":"n1821015322","loc":[-85.5456771,42.0162413]},"n1821015323":{"id":"n1821015323","loc":[-85.5936618,41.9829096]},"n1821015325":{"id":"n1821015325","loc":[-85.5656931,42.0086582]},"n1821015326":{"id":"n1821015326","loc":[-85.5448456,42.0150975]},"n1821015327":{"id":"n1821015327","loc":[-85.5220039,42.027615]},"n1821015329":{"id":"n1821015329","loc":[-85.517884,42.0354885]},"n1821015330":{"id":"n1821015330","loc":[-85.5576666,42.0101671]},"n1821015332":{"id":"n1821015332","loc":[-85.5368754,42.0181402]},"n1821015333":{"id":"n1821015333","loc":[-85.5367078,42.0181145]},"n1821015334":{"id":"n1821015334","loc":[-85.5903909,41.9904316]},"n1821015335":{"id":"n1821015335","loc":[-85.5430767,42.0163587]},"n1821015336":{"id":"n1821015336","loc":[-85.5277492,42.0252878]},"n1821015337":{"id":"n1821015337","loc":[-85.5312146,42.0236898]},"n1821015338":{"id":"n1821015338","loc":[-85.5886568,41.991614]},"n1821015339":{"id":"n1821015339","loc":[-85.5782498,42.0040883]},"n1821015341":{"id":"n1821015341","loc":[-85.562233,42.0076457]},"n1821015342":{"id":"n1821015342","loc":[-85.588626,41.9952479]},"n1821015343":{"id":"n1821015343","loc":[-85.5762865,42.005033]},"n1821015344":{"id":"n1821015344","loc":[-85.5850841,41.9971478]},"n1821015346":{"id":"n1821015346","loc":[-85.5643144,42.0076936]},"n1821015347":{"id":"n1821015347","loc":[-85.5164893,42.0359467]},"n1821015348":{"id":"n1821015348","loc":[-85.5906846,41.9903541]},"n1821015349":{"id":"n1821015349","loc":[-85.557688,42.0107769]},"n1821015350":{"id":"n1821015350","loc":[-85.5363698,42.0181424]},"n1821015351":{"id":"n1821015351","loc":[-85.5939636,41.9801918]},"n1821015352":{"id":"n1821015352","loc":[-85.5524041,42.0131644]},"n1821015354":{"id":"n1821015354","loc":[-85.5308606,42.0236221]},"n1821015355":{"id":"n1821015355","loc":[-85.5877449,41.9932367]},"n1821015356":{"id":"n1821015356","loc":[-85.519885,42.0318586]},"n1821015357":{"id":"n1821015357","loc":[-85.5454035,42.0168431]},"n1821015358":{"id":"n1821015358","loc":[-85.5970629,41.9781881]},"n1821015359":{"id":"n1821015359","loc":[-85.5932541,41.9844767]},"n1821015360":{"id":"n1821015360","loc":[-85.5970736,41.9778252]},"n1821015361":{"id":"n1821015361","loc":[-85.537031,42.0181601]},"n1821015362":{"id":"n1821015362","loc":[-85.5548355,42.0105156]},"n1821015363":{"id":"n1821015363","loc":[-85.5168648,42.0336158]},"n1821015365":{"id":"n1821015365","loc":[-85.5870435,41.9919507]},"n1821015366":{"id":"n1821015366","loc":[-85.5719681,42.0075443]},"n1821015367":{"id":"n1821015367","loc":[-85.5969985,41.9780446]},"n1821015368":{"id":"n1821015368","loc":[-85.5926761,41.98528]},"n1821015369":{"id":"n1821015369","loc":[-85.5224009,42.0293444]},"n1821015371":{"id":"n1821015371","loc":[-85.518737,42.0322651]},"n1821015372":{"id":"n1821015372","loc":[-85.6064573,41.9726465]},"n1821015373":{"id":"n1821015373","loc":[-85.5201103,42.0313088]},"n1821015375":{"id":"n1821015375","loc":[-85.5378182,42.0186844]},"n1821015376":{"id":"n1821015376","loc":[-85.6109741,41.9706882]},"n1821015377":{"id":"n1821015377","loc":[-85.5993333,41.9785488]},"n1821015378":{"id":"n1821015378","loc":[-85.5889787,41.9907368]},"n1821015380":{"id":"n1821015380","loc":[-85.6060161,41.9737375]},"n1821015381":{"id":"n1821015381","loc":[-85.5743016,42.0053679]},"n1821015382":{"id":"n1821015382","loc":[-85.6014724,41.9776099]},"n1821015383":{"id":"n1821015383","loc":[-85.5574426,42.0091644]},"n1821015385":{"id":"n1821015385","loc":[-85.5208613,42.0309302]},"n1821015386":{"id":"n1821015386","loc":[-85.5919023,41.9837789]},"n1821015387":{"id":"n1821015387","loc":[-85.5455484,42.0160221]},"n1821015392":{"id":"n1821015392","loc":[-85.5801757,42.0028964]},"n1821015395":{"id":"n1821015395","loc":[-85.5493785,42.0139974]},"n1821015396":{"id":"n1821015396","loc":[-85.5449475,42.015488]},"n1821015398":{"id":"n1821015398","loc":[-85.611123,41.9706627]},"n1821015400":{"id":"n1821015400","loc":[-85.5935706,41.9822477]},"n1821015401":{"id":"n1821015401","loc":[-85.5724254,42.0073508]},"n1821015403":{"id":"n1821015403","loc":[-85.5486812,42.0143442]},"n1821015404":{"id":"n1821015404","loc":[-85.5161835,42.0327711]},"n1821015406":{"id":"n1821015406","loc":[-85.5921705,41.9851107]},"n1821015407":{"id":"n1821015407","loc":[-85.531912,42.0234069]},"n1821015410":{"id":"n1821015410","loc":[-85.5292566,42.024176]},"n1821015411":{"id":"n1821015411","loc":[-85.5845316,41.9948315]},"n1821015413":{"id":"n1821015413","loc":[-85.5217947,42.0280413]},"n1821015414":{"id":"n1821015414","loc":[-85.5527367,42.013272]},"n1821015415":{"id":"n1821015415","loc":[-85.5191179,42.0321973]},"n1821015416":{"id":"n1821015416","loc":[-85.5540241,42.0128655]},"n1821015418":{"id":"n1821015418","loc":[-85.5272892,42.0254849]},"n1821015419":{"id":"n1821015419","loc":[-85.5449744,42.016867]},"n1821015420":{"id":"n1821015420","loc":[-85.5852665,41.9986787]},"n1821015421":{"id":"n1821015421","loc":[-85.6102701,41.972186]},"n1821015423":{"id":"n1821015423","loc":[-85.6026365,41.9764972]},"n1821015427":{"id":"n1821015427","loc":[-85.5898692,41.9841498]},"n1821015429":{"id":"n1821015429","loc":[-85.5422546,42.0183855]},"n1821015430":{"id":"n1821015430","loc":[-85.5866505,41.9925549]},"n1821015431":{"id":"n1821015431","loc":[-85.5234376,42.0273577]},"n1821015432":{"id":"n1821015432","loc":[-85.6096746,41.9727284]},"n1821015433":{"id":"n1821015433","loc":[-85.5824891,42.0021567]},"n1821015434":{"id":"n1821015434","loc":[-85.5923905,41.9841139]},"n1821015435":{"id":"n1821015435","loc":[-85.5874565,41.9948014]},"n1821015437":{"id":"n1821015437","loc":[-85.6055279,41.9734423]},"n1821015438":{"id":"n1821015438","loc":[-85.5299379,42.0237376]},"n1821015439":{"id":"n1821015439","loc":[-85.5155022,42.0383651]},"n1821015442":{"id":"n1821015442","loc":[-85.527422,42.0254711]},"n1821015443":{"id":"n1821015443","loc":[-85.5920699,41.9849291]},"n1821015444":{"id":"n1821015444","loc":[-85.5639711,42.0077494]},"n1821015445":{"id":"n1821015445","loc":[-85.5162586,42.0361777]},"n1821015446":{"id":"n1821015446","loc":[-85.5220039,42.029695]},"n1821015448":{"id":"n1821015448","loc":[-85.5176641,42.0356956]},"n1821015449":{"id":"n1821015449","loc":[-85.5930556,41.9841577]},"n1821015451":{"id":"n1821015451","loc":[-85.5320783,42.0228848]},"n1821015452":{"id":"n1821015452","loc":[-85.5170096,42.0357235]},"n1821015453":{"id":"n1821015453","loc":[-85.5571355,42.009613]},"n1821015454":{"id":"n1821015454","loc":[-85.5609979,42.009059]},"n1821015455":{"id":"n1821015455","loc":[-85.6097336,41.9708342]},"n1821015456":{"id":"n1821015456","loc":[-85.5884476,41.9904218]},"w170843846":{"id":"w170843846","tags":{"waterway":"river"},"nodes":["n1819790555","n1819790762","n1819790547","n1819790618","n1819790898","n1819790796","n1819790534","n1819790543","n1819790541","n1819790687","n1819790877","n1819790811","n1819790670"]},"w209083541":{"id":"w209083541","tags":{"name":"Portage River","waterway":"river"},"nodes":["n1821014848","n1821015156","n1821015439","n1821014763","n1821014824","n1821015274","n1821014764","n1821014791","n1821014957","n1821015217","n1821015445","n1821015347","n1821014893","n1821015452","n1821015017","n1821015448","n1821014968","n1821015329","n1821015321","n1821014992","n1821014948","n1821014757","n1821014983","n1821015312","n1821015363","n1821014924","n1821014873","n1821014932","n1821014668","n1821015404","n1821014716","n1821015243","n1821015265","n1821014710","n1821015371","n1821015415","n1821014870","n1821015356","n1821015373","n1821014681","n1821014714","n1821015385","n1821014911","n1821015057","n1821014867","n1821014998","n1821015142","n1821015234","n1821015446","n1821014862","n1821015369","n1821014945","n1821015003","n1821014667","n1821015413","n1821015256","n1821015327","n1821015160","n1821014907","n1821015431","n1821015172","n1821015034","n1821014741","n1821015033","n1821015239","n1821015007","n1821015316","n1821015285","n1821014633","n1821015263","n1821015069","n1821014846","n1821014779","n1821015011","n1821015012","n1821014845","n1821015418","n1821015442","n1821015266","n1821015336","n1821014755","n1821015188","n1821014925","n1821014816","n1821014869","n1821014967","n1821015286","n1821015147","n1821015410","n1821015126","n1821015438","n1821015018","n1821015354","n1821015337","n1821014766","n1821014740","n1821015228","n1821015173","n1821015407","n1821015076","n1821015451","n1821015024","n1821015314","n1821014784","n1821015045","n1821014735","n1821015205","n1821014986","n1821015240","n1821015098","n1821014825","n1821015302","n1821014918","n1821014718","n1821014896","n1821014853","n1821015194","n1821015165","n1821015213","n1821014991","n1821015350","n1821015333","n1821015332","n1821015361","n1821015060","n1821014914","n1821015375","n1821015315","n1821015307","n1821014906","n1821014751","n1821014666","n1821015218","n1821014817","n1821015118","n1821014674","n1821015038","n1821014973","n1821015429","n1821015183","n1821015046","n1821014803","n1821015140","n1821015009","n1821014749","n1821015335","n1821014711","n1821014854","n1821015278","n1821015419","n1821014648","n1821015357","n1821014637","n1821014988","n1821015322","n1821015387","n1821015042","n1821014833","n1821015396","n1821015326","n1821014691","n1821015149","n1821015204","n1821015122","n1821014782","n1821014982","n1821014921","n1821014936","n1821014969","n1821014881","n1821015403","n1821014805","n1821015395","n1821014892","n1821014826","n1821014844","n1821015107","n1821015014","n1821014955","n1821015352","n1821015414","n1821014746","n1821015209","n1821014770","n1821015416","n1821014661","n1821014857","n1821014814","n1821014754","n1821014721","n1821014727","n1821015362","n1821015029","n1821015246","n1821015189","n1821014627","n1821015269","n1821014808","n1821014962","n1821015349","n1821015041","n1821014722","n1821015330","n1821015453","n1821015067","n1821014643","n1821014802","n1821015383","n1821015151","n1821015250","n1821015245","n1821014772","n1821014899","n1821015222","n1821015121","n1821014951","n1821015176","n1821015219","n1821015454","n1821014972","n1821014917","n1821015182","n1821015166","n1821015145","n1821014910","n1821015082","n1821014678","n1821014806","n1821015141","n1821015341","n1821014788","n1821015097","n1821014995","n1821015444","n1821015346","n1821015101","n1821015129","n1821015123","n1821015132","n1821015190","n1821015146","n1821015325","n1821015191","n1821015072","n1821015100","n1821015174","n1821015238","n1821015215","n1821014700","n1821015242","n1821014841","n1821014905","n1821014874","n1821014883","n1821014729","n1821014866","n1821014828","n1821015295","n1821014931","n1821014859","n1821014912","n1821014783","n1821014752","n1821014961","n1821015366","n1821015401","n1821015169","n1821015318","n1821014996","n1821014747","n1821014963","n1821014670","n1821015186","n1821015231","n1821015157","n1821014812","n1821015381","n1821014887","n1821015138","n1821014704","n1821014787","n1821014922","n1821015290","n1821015343","n1821014651","n1821014980","n1821014960","n1821015244","n1821015236","n1821015006","n1821014694","n1821014759","n1821015207","n1821015276","n1821015065","n1821014863","n1821014660","n1821014902","n1821014645","n1821015339","n1821014871","n1821015096","n1821015299","n1821014798","n1821014638","n1821015392","n1821014835","n1821014762","n1821014642","n1821015433","n1821014786","n1821015134","n1821014855","n1821015184","n1821014850","n1821015293","n1821015233","n1821015227","n1821014876","n1821014985","n1821014843","n1821015420","n1821015197","n1821015192","n1821015292","n1821015344","n1821014742","n1821014726","n1821015237","n1821014796","n1821014908","n1821014975","n1821014769","n1821014688","n1821014860","n1821014895","n1821014676","n1821015411","n1821014736","n1821015164","n1821014647","n1821015144","n1821014919","n1821015220","n1821015254","n1821015435","n1821015308","n1821015342","n1821014830","n1821015273","n1821014658","n1821014781","n1821015087","n1821015139","n1821015304","n1821014839","n1821015048","n1821015115","n1821015355","n1821015226","n1821015177","n1821015430","n1821014965","n1821014725","n1821015365","n1821015171","n1821015073","n1821015125","n1821015338","n1821015111","n1821014950","n1821015378","n1821015258","n1821015456","n1821015106","n1821014832","n1821014888","n1821014795","n1821014872","n1821014810","n1821014705","n1821014804","n1821014820","n1821015283","n1821014938","n1821014689","n1821015259","n1821015334","n1821015348","n1821014635","n1821015179","n1821014864","n1821014890","n1821015020","n1821014898","n1821015287","n1821015120","n1821014984","n1821014743","n1821014790","n1821014765","n1821014777","n1821015095","n1821014653","n1821015135","n1821014836","n1821014964","n1821014974","n1821014636","n1821014682","n1821014663","n1821014665","n1821015109","n1821015155","n1821014930","n1821014669","n1821015004","n1821015427","n1821014916","n1821015093","n1821015086","n1821015386","n1821014799","n1821014913","n1821015434","n1821014728","n1821014900","n1821015068","n1821015039","n1821015443","n1821015406","n1821015280","n1821015319","n1821015368","n1821014774","n1821015090","n1821015175","n1821015195","n1821014687","n1821015359","n1821015449","n1821014956","n1821014838","n1821014768","n1821014698","n1821015323","n1821014756","n1821015255","n1821015400","n1821014717","n1821014868","n1821014778","n1821015214","n1821014944","n1821014697","n1821014671","n1821014928","n1821015294","n1821014822","n1821015284","n1821015351","n1821015022","n1821015133","n1821014644","n1821015010","n1821014625","n1821014657","n1821014946","n1821015099","n1821015114","n1821014629","n1821014865","n1821014997","n1821014926","n1821014933","n1821015199","n1821014819","n1821015080","n1821014692","n1821014677","n1821015358","n1821015367","n1821015360","n1821015105","n1821015247","n1821015005","n1821014809","n1821014794","n1821014761","n1821014879","n1821014801","n1821015377","n1821015059","n1821014730","n1821015050","n1821015271","n1821015143","n1821014989","n1821015019","n1821014672","n1821014649","n1821014684","n1821014703","n1821015021","n1821015382","n1821014842","n1821014720","n1821014847","n1821015104","n1821014987","n1821014886","n1821015267","n1821015221","n1821015015","n1821015423","n1821014954","n1821014903","n1821014939","n1821015212","n1821014789","n1821014712","n1821014708","n1821015078","n1821015277","n1821015249","n1821014646","n1821014793","n1821015053","n1821014707","n1821015306","n1821015112","n1821015288","n1821015380","n1821015437","n1821015178","n1821015158","n1821015272","n1821015235","n1821015163","n1821015154","n1821015253","n1821014632","n1821015372","n1821015103","n1821015311","n1821015301","n1821014885","n1821014811","n1821014977","n1821015051","n1821014942","n1821014745","n1821015432","n1821015075","n1821014664","n1821014695","n1821015116","n1821014639","n1821015421","n1821015248","n1821014758","n1821014834","n1821015083","n1821015455","n1821015241","n1821015108","n1821014713","n1821015137","n1821015055","n1821015211","n1821014904","n1821015376","n1821015398","n1821014771","n1821014840","n1821015062","n1819790554","n1819790560","n1819790767","n1819790696","n1819790706","n1819790606","n1819790607","n1819790544","n1819790779","n1819790760","n1819790926","n1819790927","n1819790647","n1819790657","n1819790649","n1819790679","n1819790915","n1819790739","n1819790549","n1819790671","n1819790686","n1819790798","n1819790791","n1819790563","n1819790720","n1819790704","n1819790795","n1819790836","n1819790622","n1819790615","n1819790654","n1819790931","n1819790595","n1819790753","n1819790612","n1819790623","n1819790564","n1819790552","n1819790645","n1819790625","n1819790605","n1819790668","n1819790731","n1819790718","n1819790781","n1819790665","n1819790659","n1819790726","n1819790642","n1819790854","n1819790697","n1819790867","n1819790833","n1819790555","n1819790774","n1819790881","n1819790530","n1819790909","n1819790891","n1819790590","n1819790738","n1819790609","n1819790528","n1819790674","n1819790583","n1819790559","n1819790863","n1819790912","n1819790685","n1819790913"]},"n185955128":{"id":"n185955128","loc":[-85.6189367,41.9519432]},"n185948818":{"id":"n185948818","loc":[-85.616755,41.952231]},"n185978819":{"id":"n185978819","loc":[-85.616773,41.954737]},"n185978821":{"id":"n185978821","loc":[-85.616699,41.954742]},"n2138420714":{"id":"n2138420714","loc":[-85.6176304,41.9515154]},"n2138420715":{"id":"n2138420715","loc":[-85.6177355,41.9515717]},"n2138420716":{"id":"n2138420716","loc":[-85.6192901,41.951573]},"n2138420718":{"id":"n2138420718","loc":[-85.6171481,41.9513579]},"n2138420719":{"id":"n2138420719","loc":[-85.6165981,41.9519199]},"n2138420720":{"id":"n2138420720","loc":[-85.6165719,41.9519922]},"n2138420721":{"id":"n2138420721","loc":[-85.6165832,41.9520757]},"n2138420722":{"id":"n2138420722","loc":[-85.6166355,41.9521453]},"n2138420723":{"id":"n2138420723","loc":[-85.6169161,41.9522788]},"n2138420724":{"id":"n2138420724","loc":[-85.6170882,41.9522538]},"n2138420725":{"id":"n2138420725","loc":[-85.6189204,41.9514674]},"n2138420726":{"id":"n2138420726","loc":[-85.6180346,41.9514735]},"n2138420727":{"id":"n2138420727","loc":[-85.6180362,41.9515719]},"n2138420728":{"id":"n2138420728","loc":[-85.6189204,41.9515727]},"n2138420744":{"id":"n2138420744","loc":[-85.618919,41.9519571]},"n2138420745":{"id":"n2138420745","loc":[-85.6194575,41.9522374]},"n2138420746":{"id":"n2138420746","loc":[-85.6181777,41.9536179]},"n2138420747":{"id":"n2138420747","loc":[-85.6176582,41.9533658]},"n2138420748":{"id":"n2138420748","loc":[-85.6179871,41.9530242]},"n2138420749":{"id":"n2138420749","loc":[-85.618429,41.9532476]},"n2138420750":{"id":"n2138420750","loc":[-85.6185538,41.9531194]},"n2138420751":{"id":"n2138420751","loc":[-85.6180765,41.9528677]},"n2138420752":{"id":"n2138420752","loc":[-85.6180394,41.9528855]},"n2138420753":{"id":"n2138420753","loc":[-85.6193752,41.9521695]},"n2138420754":{"id":"n2138420754","loc":[-85.6181374,41.9535376]},"n2138420755":{"id":"n2138420755","loc":[-85.6179898,41.9535545]},"n2138420756":{"id":"n2138420756","loc":[-85.6177286,41.9534228]},"n2138420757":{"id":"n2138420757","loc":[-85.6181011,41.9530292]},"n2138420759":{"id":"n2138420759","loc":[-85.6185158,41.9531194]},"n2138420760":{"id":"n2138420760","loc":[-85.6191318,41.9520425]},"n2138420761":{"id":"n2138420761","loc":[-85.6182348,41.9529815]},"n2138420762":{"id":"n2138420762","loc":[-85.6184853,41.9524248]},"n2138420763":{"id":"n2138420763","loc":[-85.6186764,41.9525193]},"n2138420764":{"id":"n2138420764","loc":[-85.6189421,41.9526483]},"n2138420765":{"id":"n2138420765","loc":[-85.6182875,41.9531222]},"n2138420766":{"id":"n2138420766","loc":[-85.6179141,41.9535163]},"n2138420767":{"id":"n2138420767","loc":[-85.6178363,41.9535735]},"n185948824":{"id":"n185948824","loc":[-85.6165667,41.9529715]},"n2138420758":{"id":"n2138420758","loc":[-85.6184408,41.953201]},"n2138422349":{"id":"n2138422349","loc":[-85.6175136,41.9533346]},"n2138422350":{"id":"n2138422350","loc":[-85.6171867,41.9531679]},"n2138422351":{"id":"n2138422351","loc":[-85.61722,41.9531305]},"n2138422352":{"id":"n2138422352","loc":[-85.6171889,41.9531158]},"n2138422353":{"id":"n2138422353","loc":[-85.6171733,41.9531284]},"n2138422354":{"id":"n2138422354","loc":[-85.616765,41.9529207]},"n2138422355":{"id":"n2138422355","loc":[-85.6167565,41.9529355]},"n2138422356":{"id":"n2138422356","loc":[-85.6164772,41.9527911]},"n2138422357":{"id":"n2138422357","loc":[-85.6168227,41.9524261]},"n2138422358":{"id":"n2138422358","loc":[-85.6171913,41.9526158]},"n2138422359":{"id":"n2138422359","loc":[-85.6172403,41.9525589]},"n2138422360":{"id":"n2138422360","loc":[-85.6172097,41.952542]},"n2138422361":{"id":"n2138422361","loc":[-85.6173948,41.9523512]},"n2138422362":{"id":"n2138422362","loc":[-85.6174256,41.9523678]},"n2138422363":{"id":"n2138422363","loc":[-85.6174831,41.9523086]},"n2138422364":{"id":"n2138422364","loc":[-85.6173316,41.9522289]},"n2138422365":{"id":"n2138422365","loc":[-85.6174507,41.9521024]},"n2138422366":{"id":"n2138422366","loc":[-85.6174773,41.9521155]},"n2138422367":{"id":"n2138422367","loc":[-85.6176577,41.9519232]},"n2138422368":{"id":"n2138422368","loc":[-85.6176336,41.9519105]},"n2138422369":{"id":"n2138422369","loc":[-85.617747,41.9517861]},"n2138422370":{"id":"n2138422370","loc":[-85.6182675,41.9520559]},"n2138422371":{"id":"n2138422371","loc":[-85.6182105,41.9521219]},"n2138422372":{"id":"n2138422372","loc":[-85.6183863,41.9522203]},"n2138422373":{"id":"n2138422373","loc":[-85.6180984,41.9525266]},"n2138422374":{"id":"n2138422374","loc":[-85.6179159,41.9524295]},"n2138422375":{"id":"n2138422375","loc":[-85.617854,41.9524979]},"n2138422376":{"id":"n2138422376","loc":[-85.6177686,41.9524531]},"n2138422377":{"id":"n2138422377","loc":[-85.6174716,41.9527765]},"n2138422378":{"id":"n2138422378","loc":[-85.6178545,41.9529756]},"n2138425424":{"id":"n2138425424","loc":[-85.6171736,41.9536385]},"n2138425425":{"id":"n2138425425","loc":[-85.6180159,41.9535782]},"n2138425426":{"id":"n2138425426","loc":[-85.6181068,41.9536282]},"n2138425427":{"id":"n2138425427","loc":[-85.6180673,41.9542678]},"n2138425428":{"id":"n2138425428","loc":[-85.6178636,41.9542634]},"n2138425429":{"id":"n2138425429","loc":[-85.6176204,41.9542046]},"n2138425430":{"id":"n2138425430","loc":[-85.6174366,41.9541031]},"n2138425431":{"id":"n2138425431","loc":[-85.6172942,41.9539781]},"n2138425432":{"id":"n2138425432","loc":[-85.6172171,41.9538399]},"n2138425433":{"id":"n2138425433","loc":[-85.6168138,41.9543266]},"n2138425434":{"id":"n2138425434","loc":[-85.6167779,41.9538098]},"n2138425435":{"id":"n2138425435","loc":[-85.6165849,41.9537073]},"n2138425441":{"id":"n2138425441","loc":[-85.616458,41.9543184]},"n2138425442":{"id":"n2138425442","loc":[-85.6166428,41.954345]},"n2138425445":{"id":"n2138425445","loc":[-85.6181332,41.9514117]},"n2138425446":{"id":"n2138425446","loc":[-85.6183263,41.9514111]},"n2138425447":{"id":"n2138425447","loc":[-85.6185033,41.9514102]},"n2138425449":{"id":"n2138425449","loc":[-85.6186809,41.9514093]},"n2138425451":{"id":"n2138425451","loc":[-85.6188681,41.9514082]},"n2138436008":{"id":"n2138436008","loc":[-85.6170474,41.9513604]},"n2138436009":{"id":"n2138436009","loc":[-85.6164937,41.9519586]},"n2138436010":{"id":"n2138436010","loc":[-85.616497,41.9520725]},"n2138436011":{"id":"n2138436011","loc":[-85.6165654,41.9521645]},"n2138436012":{"id":"n2138436012","loc":[-85.6166631,41.9522178]},"n2138436013":{"id":"n2138436013","loc":[-85.6167327,41.9522554]},"n2138436014":{"id":"n2138436014","loc":[-85.6172383,41.9525125]},"n2138439319":{"id":"n2138439319","loc":[-85.6170432,41.9524057]},"n2138439320":{"id":"n2138439320","loc":[-85.617691,41.9517107]},"n2138439321":{"id":"n2138439321","loc":[-85.6177727,41.9516794]},"n2138439322":{"id":"n2138439322","loc":[-85.619085,41.9516811]},"n2138439323":{"id":"n2138439323","loc":[-85.6179432,41.952895]},"n2138439324":{"id":"n2138439324","loc":[-85.6180389,41.9529384]},"n2138439325":{"id":"n2138439325","loc":[-85.6176303,41.9533604]},"n2138439326":{"id":"n2138439326","loc":[-85.6175538,41.9534396]},"n2138439327":{"id":"n2138439327","loc":[-85.6173806,41.9523658]},"n2138439328":{"id":"n2138439328","loc":[-85.6171841,41.9522542]},"n2138439329":{"id":"n2138439329","loc":[-85.6172077,41.9524958]},"n2138439330":{"id":"n2138439330","loc":[-85.6171235,41.9525809]},"n2138439331":{"id":"n2138439331","loc":[-85.6180938,41.9527349]},"n2138439332":{"id":"n2138439332","loc":[-85.6177023,41.9525253]},"n2138439333":{"id":"n2138439333","loc":[-85.6175543,41.9526865]},"n2138439334":{"id":"n2138439334","loc":[-85.6179589,41.9528783]},"n185948820":{"id":"n185948820","loc":[-85.6163249,41.952701]},"n185948822":{"id":"n185948822","loc":[-85.6163757,41.952855]},"n185955123":{"id":"n185955123","loc":[-85.6198103,41.9510408]},"n185958839":{"id":"n185958839","loc":[-85.611651,41.954761]},"n185965033":{"id":"n185965033","loc":[-85.614195,41.954754]},"n185976502":{"id":"n185976502","loc":[-85.617375,41.947559]},"n185976504":{"id":"n185976504","loc":[-85.6174164,41.9510804]},"n185978828":{"id":"n185978828","loc":[-85.613542,41.954756]},"n185978830":{"id":"n185978830","loc":[-85.610373,41.954774]},"n2138420713":{"id":"n2138420713","loc":[-85.6174641,41.9506942]},"n2138420717":{"id":"n2138420717","loc":[-85.6173027,41.9512895]},"n2138420768":{"id":"n2138420768","loc":[-85.61745,41.9501974]},"n2138420773":{"id":"n2138420773","loc":[-85.6174135,41.9489136]},"n2138425436":{"id":"n2138425436","loc":[-85.6159148,41.9538036]},"n2138425437":{"id":"n2138425437","loc":[-85.6159534,41.9539677]},"n2138425438":{"id":"n2138425438","loc":[-85.6160306,41.9540846]},"n2138425439":{"id":"n2138425439","loc":[-85.6161354,41.954181]},"n2138425440":{"id":"n2138425440","loc":[-85.6162733,41.954263]},"n2138425443":{"id":"n2138425443","loc":[-85.6183273,41.9510826]},"n2138425444":{"id":"n2138425444","loc":[-85.6181354,41.9510835]},"n2138425448":{"id":"n2138425448","loc":[-85.6185033,41.9510816]},"n2138425450":{"id":"n2138425450","loc":[-85.6186816,41.9510808]},"n2138425452":{"id":"n2138425452","loc":[-85.6188641,41.9510818]},"n2138435984":{"id":"n2138435984","loc":[-85.6167607,41.9501009]},"n2138436000":{"id":"n2138436000","loc":[-85.6173169,41.947558]},"n2138436001":{"id":"n2138436001","loc":[-85.6173362,41.948883]},"n2138436002":{"id":"n2138436002","loc":[-85.6167791,41.9492952]},"n2138436003":{"id":"n2138436003","loc":[-85.6167543,41.949349]},"n2138436004":{"id":"n2138436004","loc":[-85.6167648,41.9509125]},"n2138436005":{"id":"n2138436005","loc":[-85.6168832,41.9510412]},"n2138436006":{"id":"n2138436006","loc":[-85.6170045,41.9511417]},"n2138436007":{"id":"n2138436007","loc":[-85.6170624,41.9512483]},"n2138436017":{"id":"n2138436017","loc":[-85.6168094,41.9492729]},"n2138436021":{"id":"n2138436021","loc":[-85.6167553,41.9494886]},"n2138436023":{"id":"n2138436023","loc":[-85.6167585,41.9499707]},"n2138436025":{"id":"n2138436025","loc":[-85.6167567,41.9497018]},"w203838284":{"id":"w203838284","tags":{"area":"yes","leisure":"pitch","sport":"baseball"},"nodes":["n2138425424","n2138425425","n2138425426","n2138425427","n2138425428","n2138425429","n2138425430","n2138425431","n2138425432","n2138425424"]},"w203837928":{"id":"w203837928","tags":{"highway":"service"},"nodes":["n2138420717","n2138420718","n2138420719","n2138420720","n2138420721","n2138420722","n185948818","n2138420723","n2138420724","n2138420715"]},"w203839364":{"id":"w203839364","tags":{"highway":"footway"},"nodes":["n2138439331","n2138439332"]},"w203837932":{"id":"w203837932","tags":{"amenity":"parking","area":"yes"},"nodes":["n2138420744","n2138420745","n2138420746","n2138420747","n2138420748","n2138420749","n2138420750","n2138420751","n2138420744"]},"w203839362":{"id":"w203839362","tags":{"highway":"footway"},"nodes":["n2138439327","n2138439328"]},"w203839363":{"id":"w203839363","tags":{"highway":"footway"},"nodes":["n2138439329","n2138439330"]},"w203837933":{"id":"w203837933","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n185955128","n2138420760","n2138420753","n2138420764","n2138420759","n2138420758","n2138420754","n2138420755","n2138420766","n2138420756"]},"w203837936":{"id":"w203837936","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2138420765","n2138420766"]},"w17966364":{"id":"w17966364","tags":{"access":"private","highway":"service","name":"Collins Dr"},"nodes":["n185961362","n185976502","n2138420773","n2138420768","n2138420713","n185976504","n2138420717","n2138420714","n2138420715","n2138420727","n2138420728","n2138420716"]},"w203838040":{"id":"w203838040","tags":{"amenity":"school","area":"yes","building":"yes","name":"Three Rivers Middle School"},"nodes":["n2138422349","n2138422350","n2138422351","n2138422352","n2138422353","n2138422354","n2138422355","n2138422356","n2138422357","n2138439330","n2138422358","n2138422359","n2138422360","n2138436014","n2138439327","n2138422361","n2138422362","n2138422363","n2138422364","n2138422365","n2138422366","n2138422367","n2138422368","n2138422369","n2138422370","n2138422371","n2138422372","n2138422373","n2138422374","n2138422375","n2138422376","n2138439332","n2138439333","n2138422377","n2138422378","n2138422349"]},"w17964049":{"id":"w17964049","tags":{"highway":"service"},"nodes":["n185955120","n185955123","n2138420716","n185955128","n2138420762","n2138420752","n2138420761","n2138420759"]},"w41074899":{"id":"w41074899","tags":{"highway":"secondary","name":"E Hoffman St","ref":"M 60"},"nodes":["n185978817","n185978819","n185978821","n185965033","n185978828","n185958839","n185978830"]},"w203839365":{"id":"w203839365","tags":{"highway":"footway"},"nodes":["n2138439333","n2138439334"]},"w203837935":{"id":"w203837935","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2138420762","n2138420763","n2138420764"]},"w203838287":{"id":"w203838287","tags":{"area":"yes","leisure":"pitch","sport":"tennis"},"nodes":["n2138425446","n2138425447","n2138425448","n2138425443","n2138425446"]},"w203837934":{"id":"w203837934","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2138420760","n2138420763","n2138420761"]},"w203838289":{"id":"w203838289","tags":{"area":"yes","leisure":"pitch","sport":"tennis"},"nodes":["n2138425449","n2138425451","n2138425452","n2138425450","n2138425449"]},"w17963047":{"id":"w17963047","tags":{"highway":"service"},"nodes":["n185948818","n2138436013","n185948820","n185948822","n185948824","n2138439326","n2138420767","n2138420766"]},"w203839091":{"id":"w203839091","tags":{"highway":"footway"},"nodes":["n185976502","n2138436000","n2138436001","n2138436017","n2138436002","n2138436003","n2138436021","n2138436025","n2138436023","n2138435984","n2138436004","n2138436005","n2138436006","n2138436007","n2138436008","n2138436009","n2138436010","n2138436011","n2138436012","n2138436013","n2138439319","n2138439329","n2138436014"]},"w204830797":{"id":"w204830797","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2138420756","n2138420757","n2138420765","n2138420758"]},"w203838288":{"id":"w203838288","tags":{"area":"yes","leisure":"pitch","sport":"tennis"},"nodes":["n2138425447","n2138425449","n2138425450","n2138425448","n2138425447"]},"w203838285":{"id":"w203838285","tags":{"area":"yes","leisure":"pitch","sport":"baseball"},"nodes":["n2138425433","n2138425434","n2138425435","n2138425436","n2138425437","n2138425438","n2138425439","n2138425440","n2138425441","n2138425442","n2138425433"]},"w203838286":{"id":"w203838286","tags":{"area":"yes","leisure":"pitch","sport":"tennis"},"nodes":["n2138425443","n2138425444","n2138425445","n2138425446","n2138425443"]},"w203837929":{"id":"w203837929","tags":{"amenity":"parking","area":"yes"},"nodes":["n2138420725","n2138420726","n2138420727","n2138420728","n2138420725"]},"w203839361":{"id":"w203839361","tags":{"highway":"footway"},"nodes":["n2138439319","n2138439328","n2138439320","n2138439321","n2138439322","n2138439331","n2138439334","n2138439323","n2138439324","n2138439325","n2138439326"]},"n394381698":{"id":"n394381698","loc":[-85.614471,41.954755]},"n394381699":{"id":"n394381699","loc":[-85.6152,41.954744]},"n394381700":{"id":"n394381700","loc":[-85.615201,41.954081]},"n394381701":{"id":"n394381701","loc":[-85.614426,41.954042]},"n394381702":{"id":"n394381702","loc":[-85.616319,41.954749]},"n394381704":{"id":"n394381704","loc":[-85.616152,41.954752]},"n394381706":{"id":"n394381706","loc":[-85.615201,41.95483]},"n394490775":{"id":"n394490775","loc":[-85.613971,41.954839]},"n394490782":{"id":"n394490782","loc":[-85.614372,41.954841]},"n185958835":{"id":"n185958835","loc":[-85.611615,41.953704]},"n185958837":{"id":"n185958837","loc":[-85.611636,41.953938]},"n185958842":{"id":"n185958842","loc":[-85.611187,41.951686]},"n185958844":{"id":"n185958844","loc":[-85.611087,41.951741]},"n185958845":{"id":"n185958845","loc":[-85.611034,41.951852]},"n185958847":{"id":"n185958847","loc":[-85.611016,41.95196]},"n185958849":{"id":"n185958849","loc":[-85.610989,41.95328]},"n185958851":{"id":"n185958851","loc":[-85.611021,41.953484]},"n185958852":{"id":"n185958852","loc":[-85.611091,41.953603]},"n185958853":{"id":"n185958853","loc":[-85.6112,41.953661]},"n185958855":{"id":"n185958855","loc":[-85.611364,41.953686]},"n185965031":{"id":"n185965031","loc":[-85.614204,41.953696]},"n185965032":{"id":"n185965032","loc":[-85.6142,41.953978]},"n185965062":{"id":"n185965062","loc":[-85.614617,41.951639]},"n185965064":{"id":"n185965064","loc":[-85.61463,41.951852]},"n185965066":{"id":"n185965066","loc":[-85.614642,41.953436]},"n185965068":{"id":"n185965068","loc":[-85.6146,41.953551]},"n185965071":{"id":"n185965071","loc":[-85.614487,41.95363]},"n185965073":{"id":"n185965073","loc":[-85.614354,41.953672]},"n185966288":{"id":"n185966288","loc":[-85.61179,41.953695]},"n185966290":{"id":"n185966290","loc":[-85.612232,41.953685]},"n185966293":{"id":"n185966293","loc":[-85.613438,41.953677]},"n185966349":{"id":"n185966349","loc":[-85.611323,41.951653]},"n185966351":{"id":"n185966351","loc":[-85.611892,41.951642]},"n185966352":{"id":"n185966352","loc":[-85.612216,41.951641]},"n185966353":{"id":"n185966353","loc":[-85.613111,41.951639]},"n185966354":{"id":"n185966354","loc":[-85.613396,41.95164]},"n185966355":{"id":"n185966355","loc":[-85.614221,41.95164]},"n185973839":{"id":"n185973839","loc":[-85.61341,41.951919]},"n185973840":{"id":"n185973840","loc":[-85.613438,41.953308]},"n185980222":{"id":"n185980222","loc":[-85.613781,41.955164]},"n185980223":{"id":"n185980223","loc":[-85.613815,41.955237]},"n185980225":{"id":"n185980225","loc":[-85.613837,41.955316]},"n185990345":{"id":"n185990345","loc":[-85.612211,41.951977]},"n185955743":{"id":"n185955743","loc":[-85.613873,41.95635]},"n185980227":{"id":"n185980227","loc":[-85.613851,41.955415]},"n185980229":{"id":"n185980229","loc":[-85.613918,41.957134]},"n394381703":{"id":"n394381703","loc":[-85.616287,41.955674]},"n394381705":{"id":"n394381705","loc":[-85.615164,41.955676]},"n394490777":{"id":"n394490777","loc":[-85.613973,41.955979]},"n394490780":{"id":"n394490780","loc":[-85.614364,41.955987]},"w17965307":{"id":"w17965307","tags":{"highway":"residential","name":"Bates Ave"},"nodes":["n185958842","n185966349","n185966351","n185966352","n185966353","n185966354","n185966355","n185965062"]},"w17967957":{"id":"w17967957","tags":{"highway":"residential","name":"Krum Ave"},"nodes":["n185966352","n185990345","n185966290"]},"w17964508":{"id":"w17964508","tags":{"highway":"residential","name":"Blossom Dr"},"nodes":["n185958842","n185958844","n185958845","n185958847","n185958849","n185958851","n185958852","n185958853","n185958855","n185958835"]},"w17964507":{"id":"w17964507","tags":{"highway":"residential","name":"Blossom Dr"},"nodes":["n185958835","n185958837","n185958839"]},"w34367080":{"id":"w34367080","tags":{"admin_level":"8","boundary":"administrative"},"nodes":["n394381699","n394381706","n394381705","n394381703","n394381702","n394381704","n394381699"]},"w17965302":{"id":"w17965302","tags":{"highway":"residential","name":"Clausen Ave"},"nodes":["n185958835","n185966288","n185966290","n185966293","n185965031"]},"w17965156":{"id":"w17965156","tags":{"highway":"residential","name":"Orchard Dr"},"nodes":["n185965062","n185965064","n185965066","n185965068","n185965071","n185965073","n185965031"]},"w34369812":{"id":"w34369812","tags":{"admin_level":"8","boundary":"administrative"},"nodes":["n394490775","n394490777","n394490780","n394490782","n394490775"]},"w17965151":{"id":"w17965151","tags":{"highway":"residential","name":"Orchard Dr"},"nodes":["n185965031","n185965032","n185965033"]},"w17966756":{"id":"w17966756","tags":{"access":"private","highway":"service","name":"Lockport Dr"},"nodes":["n185978828","n185980222","n185980223","n185980225","n185980227","n185955743","n185980229"]},"w17966056":{"id":"w17966056","tags":{"highway":"residential","name":"Angell Ave"},"nodes":["n185966354","n185973839","n185973840","n185966293"]},"w34367079":{"id":"w34367079","tags":{"admin_level":"8","boundary":"administrative"},"nodes":["n394381700","n394381701","n394381698","n394381699","n394381700"]},"n185955744":{"id":"n185955744","loc":[-85.611753,41.956208]},"n185988932":{"id":"n185988932","loc":[-85.6159,41.956336]},"n185988934":{"id":"n185988934","loc":[-85.6159158,41.9590646]},"n185988935":{"id":"n185988935","loc":[-85.6157358,41.959364],"tags":{"highway":"turning_circle"}},"n2138447007":{"id":"n2138447007","loc":[-85.6130784,41.9590689]},"n2138447008":{"id":"n2138447008","loc":[-85.6133328,41.9593805]},"n2138447003":{"id":"n2138447003","loc":[-85.610238,41.9547745]},"n2138447004":{"id":"n2138447004","loc":[-85.6102652,41.9566041]},"n2138447005":{"id":"n2138447005","loc":[-85.610325,41.9568823]},"n2138447006":{"id":"n2138447006","loc":[-85.6105644,41.9571383]},"n2138447009":{"id":"n2138447009","loc":[-85.6135946,41.959948]},"n2138447010":{"id":"n2138447010","loc":[-85.6136071,41.9629372]},"n2138447011":{"id":"n2138447011","loc":[-85.6134392,41.9633182]},"n2138447012":{"id":"n2138447012","loc":[-85.6130151,41.9636073]},"n2138447013":{"id":"n2138447013","loc":[-85.6122729,41.9637125]},"n2138447014":{"id":"n2138447014","loc":[-85.6056682,41.963752]},"w17964174":{"id":"w17964174","tags":{"access":"private","highway":"service"},"nodes":["n185955743","n185955744"]},"w17967743":{"id":"w17967743","tags":{"access":"private","highway":"service","name":"Manistee River Rd"},"nodes":["n185971574","n185988932","n185971407","n185981301","n185967987","n185988934","n185988935"]},"w203839666":{"id":"w203839666","tags":{"highway":"residential","name":"Hov Aire Drive"},"nodes":["n2138447003","n2138447004","n2138447005","n2138447006","n2138447007","n2138447008","n2138447009","n2138447010","n2138447011","n2138447012","n2138447013","n2138447014"]}};
56744 function pointBox(point, context) {
56745 var rect = context.surfaceRect();
56746 point = context.projection(point);
56748 left: point[0] + rect.left - 30,
56749 top: point[1] + rect.top - 50,
56756 function pad$1(box, padding, context) {
56757 if (box instanceof Array) {
56758 var rect = context.surfaceRect();
56759 box = context.projection(box);
56761 left: box[0] + rect.left,
56762 top: box[1] + rect.top
56766 left: box.left - padding,
56767 top: box.top - padding,
56768 width: (box.width || 0) + 2 * padding,
56769 height: (box.width || 0) + 2 * padding
56774 function icon(name, svgklass) {
56775 return '<svg class="icon ' + (svgklass || '') + '">' +
56776 '<use xlink:href="' + name + '"></use></svg>';
56779 function uiIntroNavigation(context, reveal) {
56780 var dispatch$$1 = dispatch('done'),
56784 title: 'intro.navigation.title'
56788 function set$$1(f, t$$1) {
56789 timeouts.push(window.setTimeout(f, t$$1));
56793 function eventCancel() {
56794 event.stopPropagation();
56795 event.preventDefault();
56799 step.enter = function() {
56800 var rect = context.surfaceRect(),
56802 left: rect.left + 10,
56803 top: rect.top + 70,
56804 width: rect.width - 70,
56805 height: rect.height - 170
56808 context.map().centerZoom([-85.63591, 41.94285], 19);
56810 reveal(map$$1, t('intro.navigation.drag'));
56812 context.map().on('move.intro', lodash.debounce(function() {
56813 context.map().on('move.intro', null);
56815 context.on('enter.intro', inspectTownHall);
56819 function townhall() {
56820 var hall = [-85.63645945147184, 41.942986488012565];
56821 var point = context.projection(hall);
56823 if (point[0] < 0 || point[0] > rect.width ||
56824 point[1] < 0 || point[1] > rect.height) {
56825 context.map().center(hall);
56828 var box = pointBox(hall, context);
56829 reveal(box, t('intro.navigation.select'));
56831 context.map().on('move.intro', function() {
56832 var box = pointBox(hall, context);
56833 reveal(box, t('intro.navigation.select'), {duration: 0});
56838 function inspectTownHall(mode) {
56839 if (mode.id !== 'select') return;
56840 context.on('enter.intro', null);
56841 context.map().on('move.intro', null);
56842 set$$1(function() {
56843 reveal('.entity-editor-pane',
56844 t('intro.navigation.pane', { button: icon('#icon-close', 'pre-text') }));
56845 context.on('exit.intro', streetSearch);
56850 function streetSearch() {
56851 context.on('exit.intro', null);
56852 reveal('.search-header input',
56853 t('intro.navigation.search', { name: t('intro.graph.spring_st') }));
56854 select('.search-header input')
56855 .on('keyup.intro', searchResult);
56859 function searchResult() {
56860 var first = select('.feature-list-item:nth-child(0n+2)'), // skip No Results item
56861 firstName = first.select('.entity-name'),
56862 name = t('intro.graph.spring_st');
56864 if (!firstName.empty() && firstName.text() === name) {
56865 reveal(first.node(), t('intro.navigation.choose', { name: name }));
56866 context.on('exit.intro', selectedStreet);
56867 select('.search-header input')
56868 .on('keydown.intro', eventCancel, true)
56869 .on('keyup.intro', null);
56874 function selectedStreet() {
56875 var springSt = [-85.63585099140167, 41.942506848938926];
56876 context.map().center(springSt);
56877 context.on('exit.intro', function() {
56878 dispatch$$1.call('done');
56881 set$$1(function() {
56882 reveal('.entity-editor-pane',
56883 t('intro.navigation.chosen', {
56884 name: t('intro.graph.spring_st'),
56885 button: icon('#icon-close', 'pre-text')
56892 step.exit = function() {
56893 timeouts.forEach(window.clearTimeout);
56894 context.map().on('move.intro', null);
56895 context.on('enter.intro', null);
56896 context.on('exit.intro', null);
56897 select('.search-header input')
56898 .on('keydown.intro', null)
56899 .on('keyup.intro', null);
56903 return utilRebind(step, dispatch$$1, 'on');
56906 function uiIntroPoint(context, reveal) {
56907 var dispatch$$1 = dispatch('done'),
56911 title: 'intro.points.title'
56915 function setTimeout(f, t$$1) {
56916 timeouts.push(window.setTimeout(f, t$$1));
56920 function eventCancel() {
56921 event.stopPropagation();
56922 event.preventDefault();
56926 step.enter = function() {
56927 context.map().centerZoom([-85.63279, 41.94394], 19);
56928 reveal('button.add-point',
56929 t('intro.points.add', { button: icon('#icon-point', 'pre-text') }),
56930 { tooltipClass: 'intro-points-add' });
56932 var corner = [-85.632481,41.944094];
56934 context.on('enter.intro', addPoint);
56937 function addPoint(mode) {
56938 if (mode.id !== 'add-point') return;
56939 context.on('enter.intro', enterSelect);
56941 var pointBox$$1 = pad$1(corner, 150, context);
56942 reveal(pointBox$$1, t('intro.points.place'));
56944 context.map().on('move.intro', function() {
56945 pointBox$$1 = pad$1(corner, 150, context);
56946 reveal(pointBox$$1, t('intro.points.place'), {duration: 0});
56951 function enterSelect(mode) {
56952 if (mode.id !== 'select') return;
56953 context.map().on('move.intro', null);
56954 context.on('enter.intro', null);
56956 setTimeout(function() {
56957 reveal('.preset-search-input',
56958 t('intro.points.search', {name: context.presets().item('amenity/cafe').name()}));
56959 select('.preset-search-input').on('keyup.intro', keySearch);
56964 function keySearch() {
56965 var first = select('.preset-list-item:first-child');
56966 if (first.classed('preset-amenity-cafe')) {
56967 reveal(first.select('.preset-list-button').node(), t('intro.points.choose'));
56968 utilBindOnce(context.history(), 'change.intro', selectedPreset);
56969 select('.preset-search-input')
56970 .on('keydown.intro', eventCancel, true)
56971 .on('keyup.intro', null);
56976 function selectedPreset() {
56977 setTimeout(function() {
56978 reveal('.entity-editor-pane', t('intro.points.describe'), {tooltipClass: 'intro-points-describe'});
56979 context.history().on('change.intro', closeEditor);
56980 context.on('exit.intro', selectPoint);
56985 function closeEditor() {
56986 select('.preset-search-input').on('keydown.intro', null);
56987 context.history().on('change.intro', null);
56988 reveal('.entity-editor-pane',
56989 t('intro.points.close', { button: icon('#icon-apply', 'pre-text') }));
56993 function selectPoint() {
56994 context.on('exit.intro', null);
56995 context.history().on('change.intro', null);
56996 context.on('enter.intro', enterReselect);
56998 var pointBox$$1 = pad$1(corner, 150, context);
56999 reveal(pointBox$$1, t('intro.points.reselect'));
57001 context.map().on('move.intro', function() {
57002 pointBox$$1 = pad$1(corner, 150, context);
57003 reveal(pointBox$$1, t('intro.points.reselect'), {duration: 0});
57008 function enterReselect(mode) {
57009 if (mode.id !== 'select') return;
57010 context.map().on('move.intro', null);
57011 context.on('enter.intro', null);
57013 setTimeout(function() {
57014 reveal('.entity-editor-pane',
57015 t('intro.points.fixname', { button: icon('#icon-apply', 'pre-text') }));
57016 context.on('exit.intro', deletePoint);
57021 function deletePoint() {
57022 context.on('exit.intro', null);
57023 context.on('enter.intro', enterDelete);
57025 var pointBox$$1 = pad$1(corner, 150, context);
57026 reveal(pointBox$$1, t('intro.points.reselect_delete'));
57028 context.map().on('move.intro', function() {
57029 pointBox$$1 = pad$1(corner, 150, context);
57030 reveal(pointBox$$1, t('intro.points.reselect_delete'), {duration: 0});
57035 function enterDelete(mode) {
57036 if (mode.id !== 'select') return;
57037 context.map().on('move.intro', null);
57038 context.on('enter.intro', null);
57039 context.on('exit.intro', deletePoint);
57040 context.map().on('move.intro', deletePoint);
57041 context.history().on('change.intro', deleted);
57043 setTimeout(function() {
57044 var node = select('.radial-menu-item-delete').node();
57045 var pointBox$$1 = pad$1(node.getBoundingClientRect(), 50, context);
57046 reveal(pointBox$$1,
57047 t('intro.points.delete', { button: icon('#operation-delete', 'pre-text') }));
57052 function deleted(changed) {
57053 if (changed.deleted().length) {
57054 dispatch$$1.call('done');
57061 step.exit = function() {
57062 timeouts.forEach(window.clearTimeout);
57063 context.on('exit.intro', null);
57064 context.on('enter.intro', null);
57065 context.map().on('move.intro', null);
57066 context.history().on('change.intro', null);
57067 select('.preset-search-input')
57068 .on('keyup.intro', null)
57069 .on('keydown.intro', null);
57072 return utilRebind(step, dispatch$$1, 'on');
57075 function uiIntroArea(context, reveal) {
57076 var dispatch$$1 = dispatch('done'),
57080 title: 'intro.areas.title'
57084 step.enter = function() {
57085 var playground = [-85.63552, 41.94159],
57086 corner = [-85.63565411045074, 41.9417715536927];
57087 context.map().centerZoom(playground, 19);
57088 reveal('button.add-area',
57089 t('intro.areas.add', { button: icon('#icon-area', 'pre-text') }),
57090 { tooltipClass: 'intro-areas-add' });
57092 context.on('enter.intro', addArea);
57095 function addArea(mode) {
57096 if (mode.id !== 'add-area') return;
57097 context.on('enter.intro', drawArea);
57099 var padding = 120 * Math.pow(2, context.map().zoom() - 19);
57100 var pointBox$$1 = pad$1(corner, padding, context);
57101 reveal(pointBox$$1, t('intro.areas.corner'));
57103 context.map().on('move.intro', function() {
57104 padding = 120 * Math.pow(2, context.map().zoom() - 19);
57105 pointBox$$1 = pad$1(corner, padding, context);
57106 reveal(pointBox$$1, t('intro.areas.corner'), {duration: 0});
57111 function drawArea(mode) {
57112 if (mode.id !== 'draw-area') return;
57113 context.on('enter.intro', enterSelect);
57115 var padding = 150 * Math.pow(2, context.map().zoom() - 19);
57116 var pointBox$$1 = pad$1(playground, padding, context);
57117 reveal(pointBox$$1, t('intro.areas.place'));
57119 context.map().on('move.intro', function() {
57120 padding = 150 * Math.pow(2, context.map().zoom() - 19);
57121 pointBox$$1 = pad$1(playground, padding, context);
57122 reveal(pointBox$$1, t('intro.areas.place'), {duration: 0});
57127 function enterSelect(mode) {
57128 if (mode.id !== 'select') return;
57129 context.map().on('move.intro', null);
57130 context.on('enter.intro', null);
57132 timeout$$1 = setTimeout(function() {
57133 reveal('.preset-search-input',
57134 t('intro.areas.search',
57135 { name: context.presets().item('leisure/playground').name() }));
57136 select('.preset-search-input').on('keyup.intro', keySearch);
57141 function keySearch() {
57142 var first = select('.preset-list-item:first-child');
57143 if (first.classed('preset-leisure-playground')) {
57144 reveal(first.select('.preset-list-button').node(), t('intro.areas.choose'));
57145 utilBindOnce(context.history(), 'change.intro', selectedPreset);
57146 select('.preset-search-input').on('keyup.intro', null);
57151 function selectedPreset() {
57153 t('intro.areas.describe', { button: icon('#icon-apply', 'pre-text') }));
57154 context.on('exit.intro', function() {
57155 dispatch$$1.call('done');
57161 step.exit = function() {
57162 window.clearTimeout(timeout$$1);
57163 context.on('enter.intro', null);
57164 context.on('exit.intro', null);
57165 context.history().on('change.intro', null);
57166 context.map().on('move.intro', null);
57167 select('.preset-search-input').on('keyup.intro', null);
57171 return utilRebind(step, dispatch$$1, 'on');
57174 function uiIntroLine(context, reveal) {
57175 var dispatch$$1 = dispatch('done'),
57179 title: 'intro.lines.title'
57183 function timeout$$1(f, t$$1) {
57184 timeouts.push(window.setTimeout(f, t$$1));
57188 function eventCancel() {
57189 event.stopPropagation();
57190 event.preventDefault();
57194 step.enter = function() {
57195 var centroid = [-85.62830, 41.95699];
57196 var midpoint = [-85.62975395449628, 41.95787501510204];
57197 var start = [-85.6297754121684, 41.95805253325314];
57198 var intersection = [-85.62974496187628, 41.95742515554585];
57200 context.map().centerZoom(start, 18);
57201 reveal('button.add-line',
57202 t('intro.lines.add', { button: icon('#icon-line', 'pre-text') }),
57203 { tooltipClass: 'intro-lines-add' });
57205 context.on('enter.intro', addLine);
57208 function addLine(mode) {
57209 if (mode.id !== 'add-line') return;
57210 context.on('enter.intro', drawLine);
57212 var padding = 150 * Math.pow(2, context.map().zoom() - 18);
57213 var pointBox$$1 = pad$1(start, padding, context);
57214 reveal(pointBox$$1, t('intro.lines.start'));
57216 context.map().on('move.intro', function() {
57217 padding = 150 * Math.pow(2, context.map().zoom() - 18);
57218 pointBox$$1 = pad$1(start, padding, context);
57219 reveal(pointBox$$1, t('intro.lines.start'), {duration: 0});
57224 function drawLine(mode) {
57225 if (mode.id !== 'draw-line') return;
57226 context.history().on('change.intro', addIntersection);
57227 context.on('enter.intro', retry);
57229 var padding = 300 * Math.pow(2, context.map().zoom() - 19);
57230 var pointBox$$1 = pad$1(midpoint, padding, context);
57231 reveal(pointBox$$1, t('intro.lines.intersect', {name: t('intro.graph.flower_st')}));
57233 context.map().on('move.intro', function() {
57234 padding = 300 * Math.pow(2, context.map().zoom() - 19);
57235 pointBox$$1 = pad$1(midpoint, padding, context);
57236 reveal(pointBox$$1, t('intro.lines.intersect', {name: t('intro.graph.flower_st')}), {duration: 0});
57241 // ended line before creating intersection
57242 function retry(mode) {
57243 if (mode.id !== 'select') return;
57244 var pointBox$$1 = pad$1(intersection, 30, context),
57245 ids = mode.selectedIDs();
57246 reveal(pointBox$$1, t('intro.lines.restart', {name: t('intro.graph.flower_st')}));
57247 select(window).on('mousedown.intro', eventCancel, true);
57249 timeout$$1(function() {
57250 context.replace(actionDeleteMultiple(ids));
57257 function addIntersection(changes) {
57258 if ( lodash.some(changes.created(), function(d) {
57259 return d.type === 'node' && context.graph().parentWays(d).length > 1;
57261 context.history().on('change.intro', null);
57262 context.on('enter.intro', enterSelect);
57264 var padding = 900 * Math.pow(2, context.map().zoom() - 19);
57265 var pointBox$$1 = pad$1(centroid, padding, context);
57266 reveal(pointBox$$1, t('intro.lines.finish'));
57268 context.map().on('move.intro', function() {
57269 padding = 900 * Math.pow(2, context.map().zoom() - 19);
57270 pointBox$$1 = pad$1(centroid, padding, context);
57271 reveal(pointBox$$1, t('intro.lines.finish'), {duration: 0});
57277 function enterSelect(mode) {
57278 if (mode.id !== 'select') return;
57279 context.map().on('move.intro', null);
57280 context.on('enter.intro', null);
57281 select('#curtain').style('pointer-events', 'all');
57287 function presetCategory() {
57288 timeout$$1(function() {
57289 select('#curtain').style('pointer-events', 'none');
57290 var road = select('.preset-category-road .preset-list-button');
57291 reveal(road.node(), t('intro.lines.road'));
57292 utilBindOnce(road, 'click.intro', roadCategory);
57297 function roadCategory() {
57298 timeout$$1(function() {
57299 var grid = select('.subgrid');
57300 reveal(grid.node(), t('intro.lines.residential'));
57301 utilBindOnce(grid.selectAll(':not(.preset-highway-residential) .preset-list-button'),
57302 'click.intro', retryPreset);
57303 utilBindOnce(grid.selectAll('.preset-highway-residential .preset-list-button'),
57304 'click.intro', roadDetails);
57309 // selected wrong road type
57310 function retryPreset() {
57311 timeout$$1(function() {
57312 var preset = select('.entity-editor-pane .preset-list-button');
57313 reveal(preset.node(), t('intro.lines.wrong_preset'));
57314 utilBindOnce(preset, 'click.intro', presetCategory);
57319 function roadDetails() {
57321 t('intro.lines.describe', { button: icon('#icon-apply', 'pre-text') }));
57322 context.on('exit.intro', function() {
57323 dispatch$$1.call('done');
57329 step.exit = function() {
57330 select(window).on('mousedown.intro', null, true);
57331 select('#curtain').style('pointer-events', 'none');
57332 timeouts.forEach(window.clearTimeout);
57333 context.on('enter.intro', null);
57334 context.on('exit.intro', null);
57335 context.map().on('move.intro', null);
57336 context.history().on('change.intro', null);
57339 return utilRebind(step, dispatch$$1, 'on');
57342 function uiIntroStartEditing(context, reveal) {
57343 var dispatch$$1 = dispatch('done', 'startEditing'),
57348 title: 'intro.startediting.title'
57352 function timeout$$1(f, t$$1) {
57353 timeouts.push(window.setTimeout(f, t$$1));
57357 step.enter = function() {
57358 reveal('.map-control.help-control',
57359 t('intro.startediting.help', { button: icon('#icon-help', 'pre-text') }));
57361 timeout$$1(function() {
57362 reveal('#bar button.save', t('intro.startediting.save'));
57365 timeout$$1(function() {
57366 reveal('#surface');
57369 timeout$$1(function() {
57370 modalSelection = uiModal(context.container());
57372 modalSelection.select('.modal')
57373 .attr('class', 'modal-splash modal col6');
57375 modalSelection.selectAll('.close').remove();
57377 var startbutton = modalSelection.select('.content')
57378 .attr('class', 'fillL')
57380 .attr('class', 'modal-section huge-modal-button')
57381 .on('click', function() {
57382 modalSelection.remove();
57387 .attr('class','illustration');
57391 .text(t('intro.startediting.start'));
57393 dispatch$$1.call('startEditing');
57398 step.exit = function() {
57399 if (modalSelection) { modalSelection.remove(); }
57400 timeouts.forEach(window.clearTimeout);
57404 return utilRebind(step, dispatch$$1, 'on');
57407 var sampleIntros = {
57408 navigation: uiIntroNavigation,
57409 point: uiIntroPoint,
57412 startEditing: uiIntroStartEditing
57416 function uiIntro(context) {
57419 function localizedName(id) {
57421 n2140018997: 'city_hall',
57422 n367813436: 'fire_department',
57423 w203988286: 'memory_isle_park',
57424 w203972937: 'riverwalk_trail',
57425 w203972938: 'riverwalk_trail',
57426 w203972940: 'riverwalk_trail',
57427 w41785752: 'w_michigan_ave',
57428 w134150789: 'w_michigan_ave',
57429 w134150795: 'w_michigan_ave',
57430 w134150800: 'w_michigan_ave',
57431 w134150811: 'w_michigan_ave',
57432 w134150802: 'e_michigan_ave',
57433 w134150836: 'e_michigan_ave',
57434 w41074896: 'e_michigan_ave',
57435 w17965834: 'spring_st',
57436 w203986457: 'scidmore_park',
57437 w203049587: 'petting_zoo',
57438 w17967397: 'n_andrews_st',
57439 w17967315: 's_andrews_st',
57440 w17967326: 'n_constantine_st',
57441 w17966400: 's_constantine_st',
57442 w170848823: 'rocky_river',
57443 w170848824: 'rocky_river',
57444 w170848331: 'rocky_river',
57445 w17967752: 'railroad_dr',
57446 w17965998: 'conrail_rr',
57447 w134150845: 'conrail_rr',
57448 w170989131: 'st_joseph_river',
57449 w143497377: 'n_main_st',
57450 w134150801: 's_main_st',
57451 w134150830: 's_main_st',
57452 w17966462: 's_main_st',
57453 w17967734: 'water_st',
57454 w17964996: 'foster_st',
57455 w170848330: 'portage_river',
57456 w17965351: 'flower_st',
57457 w17965502: 'elm_st',
57458 w17965402: 'walnut_st',
57459 w17964793: 'morris_ave',
57460 w17967444: 'east_st',
57461 w17966984: 'portage_ave'
57464 return features[id] && t('intro.graph.' + features[id]);
57468 var introGraph = {};
57470 for (var key in dataIntroGraph) {
57471 introGraph[key] = osmEntity$$1(dataIntroGraph[key]);
57472 var name = localizedName(key);
57474 introGraph[key].tags.name = name;
57479 function intro(selection$$1) {
57480 context.enter(modeBrowse$$1(context));
57482 // Save current map state
57483 var history = context.history().toJSON(),
57484 hash = window.location.hash,
57485 center = context.map().center(),
57486 zoom$$1 = context.map().zoom(),
57487 background = context.background().baseLayerSource(),
57488 opacity = selectAll('#map .layer-background').style('opacity'),
57489 loadedTiles = context.connection().loadedTiles(),
57490 baseEntities = context.history().graph().base().entities;
57493 context.inIntro(true);
57495 // Load semi-real data used in intro
57496 context.connection().toggle(false).reset();
57497 context.history().reset();
57499 context.history().merge(values(coreGraph$$1().load(introGraph).entities));
57500 context.background().bing();
57502 selectAll('#map .layer-background').style('opacity', 1);
57504 var curtain = d3curtain();
57505 selection$$1.call(curtain);
57508 function reveal(box, text$$1, options) {
57509 options = options || {};
57510 curtain.reveal(box,
57512 options.tooltipClass || '',
57517 var steps = ['navigation', 'point', 'area', 'line', 'startEditing'].map(function(step, i) {
57518 var s = sampleIntros[step](context, reveal)
57519 .on('done', function() {
57520 entered.filter(function(d) {
57521 return d.title === s.title;
57522 }).classed('finished', true);
57523 enter(steps[i + 1]);
57528 steps[steps.length - 1].on('startEditing', function() {
57531 selectAll('#map .layer-background').style('opacity', opacity);
57532 context.connection().toggle(true).reset().loadedTiles(loadedTiles);
57533 context.history().reset().merge(values(baseEntities));
57534 context.background().baseLayerSource(background);
57535 if (history) context.history().fromJSON(history, false);
57536 context.map().centerZoom(center, zoom$$1);
57537 window.location.replace(hash);
57538 context.inIntro(false);
57541 var navwrap = selection$$1
57543 .attr('class', 'intro-nav-wrap fillD');
57545 var buttonwrap = navwrap
57547 .attr('class', 'joined')
57548 .selectAll('button.step');
57550 var entered = buttonwrap
57554 .attr('class', 'step')
57555 .on('click', enter);
57559 .text(function(d) { return t(d.title); });
57563 .attr('class', 'status')
57564 .text(' - ' + t('intro.done'));
57569 function enter(newStep) {
57570 if (step) { step.exit(); }
57572 context.enter(modeBrowse$$1(context));
57577 entered.classed('active', function(d) {
57578 return d.title === step.title;
57588 function uiHelp(context) {
57593 'help.editing_saving',
57602 var docs = docKeys.map(function(key) {
57603 var text$$1 = t(key);
57605 title: text$$1.split('\n')[0].replace('#', '').trim(),
57606 html: marked(text$$1.split('\n').slice(1).join('\n'))
57611 function help(selection$$1) {
57618 function toggle() {
57619 if (event) event.preventDefault();
57620 tooltipBehavior.hide(button);
57621 setVisible(!button.classed('active'));
57625 function setVisible(show) {
57626 if (show !== shown) {
57627 button.classed('active', show);
57631 selection$$1.on('mousedown.help-inside', function() {
57632 return event.stopPropagation();
57634 pane.style('display', 'block')
57635 .style('right', '-500px')
57638 .style('right', '0px');
57640 pane.style('right', '0px')
57643 .style('right', '-500px')
57644 .on('end', function() {
57645 select(this).style('display', 'none');
57647 selection$$1.on('mousedown.help-inside', null);
57653 function clickHelp(d, i) {
57654 pane.property('scrollTop', 0);
57655 doctitle.html(d.title);
57657 body.selectAll('a')
57658 .attr('target', '_blank');
57659 menuItems.classed('selected', function(m) {
57660 return m.title === d.title;
57666 var prevLink = nav.append('a')
57667 .attr('class', 'previous')
57668 .on('click', function() {
57669 clickHelp(docs[i - 1], i - 1);
57671 prevLink.append('span').html('◄ ' + docs[i - 1].title);
57673 if (i < docs.length - 1) {
57674 var nextLink = nav.append('a')
57675 .attr('class', 'next')
57676 .on('click', function() {
57677 clickHelp(docs[i + 1], i + 1);
57679 nextLink.append('span').html(docs[i + 1].title + ' ►');
57684 function clickWalkthrough() {
57685 select(document.body).call(uiIntro(context));
57690 var pane = selection$$1.append('div')
57691 .attr('class', 'help-wrap map-overlay fillL col5 content hide'),
57692 tooltipBehavior = tooltip()
57693 .placement((textDirection === 'rtl') ? 'right' : 'left')
57695 .title(uiTooltipHtml(t('help.title'), key)),
57696 button = selection$$1.append('button')
57697 .attr('tabindex', -1)
57698 .on('click', toggle)
57699 .call(svgIcon('#icon-help', 'light'))
57700 .call(tooltipBehavior),
57704 var toc = pane.append('ul')
57705 .attr('class', 'toc');
57707 var menuItems = toc.selectAll('li')
57712 .html(function(d) { return d.title; })
57713 .on('click', clickHelp);
57716 .attr('class','walkthrough')
57718 .text(t('splash.walkthrough'))
57719 .on('click', clickWalkthrough);
57721 var content = pane.append('div')
57722 .attr('class', 'left-content');
57724 var doctitle = content.append('h2')
57725 .text(t('help.title'));
57727 var body = content.append('div')
57728 .attr('class', 'body');
57730 var nav = content.append('div')
57731 .attr('class', 'nav');
57733 clickHelp(docs[0], 0);
57735 var keybinding = d3keybinding('help')
57743 context.surface().on('mousedown.help-outside', hide);
57744 context.container().on('mousedown.help-outside', hide);
57750 function uiInfo(context) {
57751 var key = uiCmd('⌘I'),
57752 isImperial = (utilDetect().locale.toLowerCase() === 'en-us'),
57756 function info(selection$$1) {
57758 function radiansToMeters(r) {
57759 // using WGS84 authalic radius (6371007.1809 m)
57760 return r * 6371007.1809;
57763 function steradiansToSqmeters(r) {
57764 // http://gis.stackexchange.com/a/124857/40446
57765 return r / (4 * Math.PI) * 510065621724000;
57769 function toLineString(feature) {
57770 if (feature.type === 'LineString') return feature;
57772 var result = { type: 'LineString', coordinates: [] };
57773 if (feature.type === 'Polygon') {
57774 result.coordinates = feature.coordinates[0];
57775 } else if (feature.type === 'MultiPolygon') {
57776 result.coordinates = feature.coordinates[0][0];
57783 function displayLength(m) {
57784 var d = m * (isImperial ? 3.28084 : 1),
57803 // drop unnecessary precision
57804 p = d > 1000 ? 0 : d > 100 ? 1 : 2;
57806 return String(d.toFixed(p)) + ' ' + unit;
57810 function displayArea(m2) {
57811 var d = m2 * (isImperial ? 10.7639111056 : 1),
57812 d1, d2, p1, p2, unit1, unit2;
57815 if (d >= 6969600) { // > 0.25mi² show mi²
57823 if (d > 4356 && d < 43560000) { // 0.1 - 1000 acres
57829 if (d >= 250000) { // > 0.25km² show km²
57837 if (d > 1000 && d < 10000000) { // 0.1 - 1000 hectares
57843 // drop unnecessary precision
57844 p1 = d1 > 1000 ? 0 : d1 > 100 ? 1 : 2;
57845 p2 = d2 > 1000 ? 0 : d2 > 100 ? 1 : 2;
57847 return String(d1.toFixed(p1)) + ' ' + unit1 +
57848 (d2 ? ' (' + String(d2.toFixed(p2)) + ' ' + unit2 + ')' : '');
57852 function redraw() {
57853 if (isHidden) return;
57855 var resolver = context.graph(),
57856 selected = lodash.filter(context.selectedIDs(), function(e) { return context.hasEntity(e); }),
57857 singular = selected.length === 1 ? selected[0] : null,
57858 extent$$1 = geoExtent$$1(),
57863 .attr('class', 'infobox-heading fillD')
57864 .text(singular || t('infobox.selected', { n: selected.length }));
57866 if (!selected.length) return;
57869 for (var i = 0; i < selected.length; i++) {
57870 entity = context.entity(selected[i]);
57871 extent$$1._extend(entity.extent(resolver));
57873 center = extent$$1.center();
57876 var list = wrap.append('ul');
57878 // multiple features, just display extent center..
57881 .text(t('infobox.center') + ': ' + center[0].toFixed(5) + ', ' + center[1].toFixed(5));
57885 // single feature, display details..
57886 if (!entity) return;
57887 var geometry = entity.geometry(resolver);
57889 if (geometry === 'line' || geometry === 'area') {
57890 var closed = (entity.type === 'relation') || (entity.isClosed() && !entity.isDegenerate()),
57891 feature = entity.asGeoJSON(resolver),
57892 length = radiansToMeters(d3GeoLength(toLineString(feature))),
57893 lengthLabel = t('infobox.' + (closed ? 'perimeter' : 'length')),
57894 centroid = d3GeoCentroid(feature);
57897 .text(t('infobox.geometry') + ': ' +
57898 (closed ? t('infobox.closed') + ' ' : '') + t('geometry.' + geometry) );
57901 var area$$1 = steradiansToSqmeters(entity.area(resolver));
57903 .text(t('infobox.area') + ': ' + displayArea(area$$1));
57907 .text(lengthLabel + ': ' + displayLength(length));
57910 .text(t('infobox.centroid') + ': ' + centroid[0].toFixed(5) + ', ' + centroid[1].toFixed(5));
57913 var toggle = isImperial ? 'imperial' : 'metric';
57915 .text(t('infobox.' + toggle))
57917 .attr('class', 'button')
57918 .on('click', function() {
57919 event.preventDefault();
57920 isImperial = !isImperial;
57925 var centerLabel = t('infobox.' + (entity.type === 'node' ? 'location' : 'center'));
57928 .text(t('infobox.geometry') + ': ' + t('geometry.' + geometry));
57931 .text(centerLabel + ': ' + center[0].toFixed(5) + ', ' + center[1].toFixed(5));
57936 function toggle() {
57938 event.preventDefault();
57941 isHidden = !isHidden;
57945 .style('display', 'block')
57946 .style('opacity', 1)
57949 .style('opacity', 0)
57950 .on('end', function() {
57951 select(this).style('display', 'none');
57955 .style('display', 'block')
57956 .style('opacity', 0)
57959 .style('opacity', 1)
57960 .on('end', function() {
57967 var wrap = selection$$1.selectAll('.infobox')
57970 wrap = wrap.enter()
57972 .attr('class', 'infobox fillD2')
57973 .style('display', (isHidden ? 'none' : 'block'))
57977 .on('drawn.info', redraw);
57981 var keybinding = d3keybinding('info')
57991 function uiMapData(context) {
57993 features = context.features().keys(),
57994 layers = context.layers(),
57995 fills = ['wireframe', 'partial', 'full'],
57996 fillDefault = context.storage('area-fill') || 'partial',
57997 fillSelected = fillDefault;
58000 function map_data(selection$$1) {
58002 function showsFeature(d) {
58003 return context.features().enabled(d);
58007 function autoHiddenFeature(d) {
58008 return context.features().autoHidden(d);
58012 function clickFeature(d) {
58013 context.features().toggle(d);
58018 function showsFill(d) {
58019 return fillSelected === d;
58023 function setFill(d) {
58024 lodash.each(fills, function(opt) {
58025 context.surface().classed('fill-' + opt, Boolean(opt === d));
58029 if (d !== 'wireframe') {
58031 context.storage('area-fill', d);
58037 function showsLayer(which) {
58038 var layer = layers.layer(which);
58040 return layer.enabled();
58046 function setLayer(which, enabled) {
58047 var layer = layers.layer(which);
58049 layer.enabled(enabled);
58055 function toggleLayer(which) {
58056 setLayer(which, !showsLayer(which));
58060 function clickGpx() {
58061 toggleLayer('gpx');
58065 function clickMapillaryImages() {
58066 toggleLayer('mapillary-images');
58067 if (!showsLayer('mapillary-images')) {
58068 setLayer('mapillary-signs', false);
58073 function clickMapillarySigns() {
58074 toggleLayer('mapillary-signs');
58078 function drawMapillaryItems(selection$$1) {
58079 var mapillaryImages = layers.layer('mapillary-images'),
58080 mapillarySigns = layers.layer('mapillary-signs'),
58081 supportsMapillaryImages = mapillaryImages && mapillaryImages.supported(),
58082 supportsMapillarySigns = mapillarySigns && mapillarySigns.supported(),
58083 showsMapillaryImages = supportsMapillaryImages && mapillaryImages.enabled(),
58084 showsMapillarySigns = supportsMapillarySigns && mapillarySigns.enabled();
58086 var mapillaryList = selection$$1
58087 .selectAll('.layer-list-mapillary')
58090 mapillaryList = mapillaryList.enter()
58092 .attr('class', 'layer-list layer-list-mapillary')
58093 .merge(mapillaryList);
58096 var mapillaryImageLayerItem = mapillaryList
58097 .selectAll('.list-item-mapillary-images')
58098 .data(supportsMapillaryImages ? [0] : []);
58100 mapillaryImageLayerItem.exit()
58103 var enterImages = mapillaryImageLayerItem.enter()
58105 .attr('class', 'list-item-mapillary-images');
58107 var labelImages = enterImages
58110 .title(t('mapillary_images.tooltip'))
58111 .placement('top'));
58115 .attr('type', 'checkbox')
58116 .on('change', clickMapillaryImages);
58120 .text(t('mapillary_images.title'));
58123 var mapillarySignLayerItem = mapillaryList
58124 .selectAll('.list-item-mapillary-signs')
58125 .data(supportsMapillarySigns ? [0] : []);
58127 mapillarySignLayerItem.exit()
58130 var enterSigns = mapillarySignLayerItem.enter()
58132 .attr('class', 'list-item-mapillary-signs');
58134 var labelSigns = enterSigns
58137 .title(t('mapillary_signs.tooltip'))
58138 .placement('top'));
58142 .attr('type', 'checkbox')
58143 .on('change', clickMapillarySigns);
58147 .text(t('mapillary_signs.title'));
58151 mapillaryImageLayerItem = mapillaryImageLayerItem
58152 .merge(enterImages);
58154 mapillaryImageLayerItem
58155 .classed('active', showsMapillaryImages)
58156 .selectAll('input')
58157 .property('checked', showsMapillaryImages);
58160 mapillarySignLayerItem = mapillarySignLayerItem
58161 .merge(enterSigns);
58163 mapillarySignLayerItem
58164 .classed('active', showsMapillarySigns)
58165 .selectAll('input')
58166 .property('disabled', !showsMapillaryImages)
58167 .property('checked', showsMapillarySigns);
58169 mapillarySignLayerItem
58170 .selectAll('label')
58171 .classed('deemphasize', !showsMapillaryImages);
58175 function drawGpxItem(selection$$1) {
58176 var gpx = layers.layer('gpx'),
58177 hasGpx = gpx && gpx.hasGpx(),
58178 showsGpx = hasGpx && gpx.enabled();
58180 var gpxLayerItem = selection$$1
58181 .selectAll('.layer-list-gpx')
58182 .data(gpx ? [0] : []);
58185 gpxLayerItem.exit()
58189 var enter = gpxLayerItem.enter()
58191 .attr('class', 'layer-list layer-list-gpx')
58193 .classed('list-item-gpx', true);
58197 .attr('class', 'list-item-gpx-extent')
58199 .title(t('gpx.zoom'))
58200 .placement((textDirection === 'rtl') ? 'right' : 'left'))
58201 .on('click', function() {
58202 event.preventDefault();
58203 event.stopPropagation();
58206 .call(svgIcon('#icon-search'));
58210 .attr('class', 'list-item-gpx-browse')
58212 .title(t('gpx.browse'))
58213 .placement((textDirection === 'rtl') ? 'right' : 'left'))
58214 .on('click', function() {
58215 select(document.createElement('input'))
58216 .attr('type', 'file')
58217 .on('change', function() {
58218 gpx.files(event.target.files);
58222 .call(svgIcon('#icon-geolocate'));
58224 var labelGpx = enter
58226 .call(tooltip().title(t('gpx.drag_drop')).placement('top'));
58230 .attr('type', 'checkbox')
58231 .on('change', clickGpx);
58235 .text(t('gpx.local_layer'));
58239 gpxLayerItem = gpxLayerItem
58243 .classed('active', showsGpx)
58244 .selectAll('input')
58245 .property('disabled', !hasGpx)
58246 .property('checked', showsGpx);
58249 .selectAll('label')
58250 .classed('deemphasize', !hasGpx);
58254 function drawList(selection$$1, data, type, name, change, active$$1) {
58255 var items = selection$$1.selectAll('li')
58263 var enter = items.enter()
58265 .attr('class', 'layer')
58268 .title(function(d) {
58269 var tip = t(name + '.' + d + '.tooltip'),
58270 key = (d === 'wireframe' ? 'W' : null);
58272 if (name === 'feature' && autoHiddenFeature(d)) {
58273 tip += '<div>' + t('map_data.autohidden') + '</div>';
58275 return uiTooltipHtml(tip, key);
58285 .attr('type', type)
58286 .attr('name', name)
58287 .on('change', change);
58291 .text(function(d) { return t(name + '.' + d + '.description'); });
58298 .classed('active', active$$1)
58299 .selectAll('input')
58300 .property('checked', active$$1)
58301 .property('indeterminate', function(d) {
58302 return (name === 'feature' && autoHiddenFeature(d));
58307 function update() {
58308 dataLayerContainer.call(drawMapillaryItems);
58309 dataLayerContainer.call(drawGpxItem);
58311 fillList.call(drawList, fills, 'radio', 'area_fill', setFill, showsFill);
58312 featureList.call(drawList, features, 'checkbox', 'feature', clickFeature, showsFeature);
58316 function hidePanel() {
58321 function togglePanel() {
58322 if (event) event.preventDefault();
58323 tooltipBehavior.hide(button);
58324 setVisible(!button.classed('active'));
58328 function toggleWireframe() {
58330 event.preventDefault();
58331 event.stopPropagation();
58333 setFill((fillSelected === 'wireframe' ? fillDefault : 'wireframe'));
58334 context.map().pan([0,0]); // trigger a redraw
58338 function setVisible(show) {
58339 if (show !== shown) {
58340 button.classed('active', show);
58345 selection$$1.on('mousedown.map_data-inside', function() {
58346 return event.stopPropagation();
58348 content.style('display', 'block')
58349 .style('right', '-300px')
58352 .style('right', '0px');
58354 content.style('display', 'block')
58355 .style('right', '0px')
58358 .style('right', '-300px')
58359 .on('end', function() {
58360 select(this).style('display', 'none');
58362 selection$$1.on('mousedown.map_data-inside', null);
58368 var content = selection$$1
58370 .attr('class', 'fillL map-overlay col3 content hide'),
58371 tooltipBehavior = tooltip()
58372 .placement((textDirection === 'rtl') ? 'right' : 'left')
58374 .title(uiTooltipHtml(t('map_data.description'), key)),
58375 button = selection$$1
58377 .attr('tabindex', -1)
58378 .on('click', togglePanel)
58379 .call(svgIcon('#icon-data', 'light'))
58380 .call(tooltipBehavior),
58385 .text(t('map_data.title'));
58391 .text(t('map_data.data_layers'))
58393 .classed('hide-toggle', true)
58394 .classed('expanded', true)
58395 .on('click', function() {
58396 var exp = select(this).classed('expanded');
58397 dataLayerContainer.style('display', exp ? 'none' : 'block');
58398 select(this).classed('expanded', !exp);
58399 event.preventDefault();
58402 var dataLayerContainer = content
58404 .attr('class', 'data-data-layers')
58405 .style('display', 'block');
58411 .text(t('map_data.fill_area'))
58413 .classed('hide-toggle', true)
58414 .classed('expanded', false)
58415 .on('click', function() {
58416 var exp = select(this).classed('expanded');
58417 fillContainer.style('display', exp ? 'none' : 'block');
58418 select(this).classed('expanded', !exp);
58419 event.preventDefault();
58422 var fillContainer = content
58424 .attr('class', 'data-area-fills')
58425 .style('display', 'none');
58427 var fillList = fillContainer
58429 .attr('class', 'layer-list layer-fill-list');
58435 .text(t('map_data.map_features'))
58437 .classed('hide-toggle', true)
58438 .classed('expanded', false)
58439 .on('click', function() {
58440 var exp = select(this).classed('expanded');
58441 featureContainer.style('display', exp ? 'none' : 'block');
58442 select(this).classed('expanded', !exp);
58443 event.preventDefault();
58446 var featureContainer = content
58448 .attr('class', 'data-feature-filters')
58449 .style('display', 'none');
58451 var featureList = featureContainer
58453 .attr('class', 'layer-list layer-feature-list');
58457 .on('change.map_data-update', update);
58459 setFill(fillDefault);
58461 var keybinding = d3keybinding('features')
58462 .on(key, togglePanel)
58463 .on('W', toggleWireframe)
58464 .on('B', hidePanel)
58465 .on('H', hidePanel);
58470 context.surface().on('mousedown.map_data-outside', hidePanel);
58471 context.container().on('mousedown.map_data-outside', hidePanel);
58478 function uiModes(context) {
58480 modeAddPoint$$1(context),
58481 modeAddLine$$1(context),
58482 modeAddArea$$1(context)
58486 function editable() {
58487 return context.editable() && context.mode().id !== 'save';
58491 return function(selection$$1) {
58492 var buttons = selection$$1.selectAll('button.add-button')
58495 buttons = buttons.enter()
58497 .attr('tabindex', -1)
58498 .attr('class', function(mode) { return mode.id + ' add-button col4'; })
58499 .on('click.mode-buttons', function(mode) {
58500 if (mode.id === context.mode().id) {
58501 context.enter(modeBrowse$$1(context));
58503 context.enter(mode);
58507 .placement('bottom')
58509 .title(function(mode) {
58510 return uiTooltipHtml(mode.description, mode.key);
58515 .on('move.modes', lodash.debounce(update, 500));
58518 .on('enter.modes', update);
58521 .each(function(d) {
58523 .call(svgIcon('#icon-' + d.button, 'pre-text'));
58528 .attr('class', 'label')
58529 .text(function(mode) { return mode.title; });
58532 .on('enter.editor', function(entered) {
58533 selection$$1.selectAll('button.add-button')
58534 .classed('active', function(mode) { return entered.button === mode.button; });
58535 context.container()
58536 .classed('mode-' + entered.id, true);
58540 .on('exit.editor', function(exited) {
58541 context.container()
58542 .classed('mode-' + exited.id, false);
58545 var keybinding = d3keybinding('mode-buttons');
58547 modes.forEach(function(m) {
58548 keybinding.on(m.key, function() {
58549 if (editable()) context.enter(m);
58557 function update() {
58558 selection$$1.selectAll('button.add-button')
58559 .property('disabled', !editable());
58564 function uiRestore(context) {
58566 return function(selection) {
58567 if (!context.history().lock() || !context.history().restorableChanges())
58570 var modalSelection = uiModal(selection, true);
58572 modalSelection.select('.modal')
58573 .attr('class', 'modal fillL col6');
58575 var introModal = modalSelection.select('.content');
58578 .attr('class','cf');
58582 .attr('class', 'modal-section')
58584 .text(t('restore.heading'));
58588 .attr('class','modal-section')
58590 .text(t('restore.description'));
58592 var buttonWrap = introModal
58594 .attr('class', 'modal-actions cf');
58596 var restore = buttonWrap
58598 .attr('class', 'restore col6')
58599 .text(t('restore.restore'))
58600 .on('click', function() {
58601 context.history().restore();
58602 modalSelection.remove();
58607 .attr('class', 'reset col6')
58608 .text(t('restore.reset'))
58609 .on('click', function() {
58610 context.history().clearSaved();
58611 modalSelection.remove();
58614 restore.node().focus();
58618 function uiSave(context) {
58619 var history = context.history(),
58623 function saving() {
58624 return context.mode().id === 'save';
58629 event.preventDefault();
58630 if (!context.inIntro() && !saving() && history.hasChanges()) {
58631 context.enter(modeSave$$1(context));
58636 function getBackground(numChanges) {
58638 if (numChanges === 0) {
58640 } else if (numChanges <= 50) {
58641 step = numChanges / 50;
58642 return interpolateRgb('#fff', '#ff8')(step); // white -> yellow
58644 step = Math.min((numChanges - 50) / 50, 1.0);
58645 return interpolateRgb('#ff8', '#f88')(step); // yellow -> red
58650 return function(selection$$1) {
58651 var tooltipBehavior = tooltip()
58652 .placement('bottom')
58654 .title(uiTooltipHtml(t('save.no_changes'), key));
58656 var button = selection$$1
58658 .attr('class', 'save col12 disabled')
58659 .attr('tabindex', -1)
58661 .call(tooltipBehavior);
58665 .attr('class', 'label')
58666 .text(t('save.title'));
58670 .attr('class', 'count')
58673 var keybinding = d3keybinding('undo-redo')
58674 .on(key, save, true);
58679 var numChanges = 0;
58682 .on('change.save', function() {
58683 var _ = history.difference().summary().length;
58684 if (_ === numChanges)
58688 tooltipBehavior.title(uiTooltipHtml(
58689 t(numChanges > 0 ? 'save.help' : 'save.no_changes'), key));
58691 var background = getBackground(numChanges);
58694 .classed('disabled', numChanges === 0)
58695 .classed('has-count', numChanges > 0)
58696 .style('background', background);
58698 button.select('span.count')
58700 .style('background', background)
58701 .style('border-color', background);
58705 .on('enter.save', function() {
58706 button.property('disabled', saving());
58707 if (saving()) button.call(tooltipBehavior.hide);
58712 function uiScale(context) {
58713 var projection = context.projection,
58714 isImperial = (utilDetect().locale.toLowerCase() === 'en-us'),
58719 function scaleDefs(loc1, loc2) {
58720 var lat = (loc2[1] + loc1[1]) / 2,
58721 conversion = (isImperial ? 3.28084 : 1),
58722 dist = geoLonToMeters(loc2[0] - loc1[0], lat) * conversion,
58723 scale = { dist: 0, px: 0, text: '' },
58724 buckets, i, val, dLon;
58727 buckets = [5280000, 528000, 52800, 5280, 500, 50, 5, 1];
58729 buckets = [5000000, 500000, 50000, 5000, 500, 50, 5, 1];
58732 // determine a user-friendly endpoint for the scale
58733 for (i = 0; i < buckets.length; i++) {
58736 scale.dist = Math.floor(dist / val) * val;
58739 scale.dist = +dist.toFixed(2);
58743 dLon = geoMetersToLon(scale.dist / conversion, lat);
58744 scale.px = Math.round(projection([loc1[0] + dLon, loc1[1]])[0]);
58747 if (scale.dist >= 5280) {
58748 scale.dist /= 5280;
58749 scale.text = String(scale.dist) + ' mi';
58751 scale.text = String(scale.dist) + ' ft';
58754 if (scale.dist >= 1000) {
58755 scale.dist /= 1000;
58756 scale.text = String(scale.dist) + ' km';
58758 scale.text = String(scale.dist) + ' m';
58766 function update(selection) {
58767 // choose loc1, loc2 along bottom of viewport (near where the scale will be drawn)
58768 var dims = context.map().dimensions(),
58769 loc1 = projection.invert([0, dims[1]]),
58770 loc2 = projection.invert([maxLength, dims[1]]),
58771 scale = scaleDefs(loc1, loc2);
58773 selection.select('#scalepath')
58774 .attr('d', 'M0.5,0.5v' + tickHeight + 'h' + scale.px + 'v-' + tickHeight);
58776 selection.select('#scaletext')
58777 .attr('x', scale.px + 8)
58778 .attr('y', tickHeight)
58783 return function(selection) {
58784 function switchUnits() {
58785 isImperial = !isImperial;
58786 selection.call(update);
58789 var g = selection.append('svg')
58790 .attr('id', 'scale')
58791 .on('click', switchUnits)
58793 .attr('transform', 'translate(10,11)');
58795 g.append('path').attr('id', 'scalepath');
58796 g.append('text').attr('id', 'scaletext');
58798 selection.call(update);
58800 context.map().on('move.scale', function() {
58807 function search(x, dims, r) {
58808 if (!dims) dims = 'NSEW';
58809 if (typeof x !== 'string') return { val: null, regex: r };
58810 r = r || /[\s\,]*([\-|\—|\―]?[0-9.]+)°? *(?:([0-9.]+)['’′‘] *)?(?:([0-9.]+)(?:''|"|”|″) *)?([NSEW])?/gi;
58812 if (!m) return { val: null, regex: r };
58813 else if (m[4] && dims.indexOf(m[4]) === -1) return { val: null, regex: r };
58815 val: (((m[1]) ? parseFloat(m[1]) : 0) +
58816 ((m[2] ? parseFloat(m[2]) / 60 : 0)) +
58817 ((m[3] ? parseFloat(m[3]) / 3600 : 0))) *
58818 ((m[4] && m[4] === 'S' || m[4] === 'W') ? -1 : 1),
58825 function pair(x, dims) {
58827 var one = search(x, dims);
58828 if (one.val === null) return null;
58829 var two = search(x, dims, one.regex);
58830 if (two.val === null) return null;
58831 // null if one/two are not contiguous.
58832 if (one.raw + two.raw !== x) return null;
58834 return swapdim(one.val, two.val, one.dim);
58836 return [one.val, two.val];
58840 function swapdim(a, b, dim) {
58841 if (dim === 'N' || dim === 'S') return [a, b];
58842 if (dim === 'W' || dim === 'E') return [b, a];
58845 function uiFeatureList(context) {
58846 var geocodeResults;
58849 function featureList(selection$$1) {
58850 var header = selection$$1.append('div')
58851 .attr('class', 'header fillL cf');
58853 header.append('h3')
58854 .text(t('inspector.feature_list'));
58856 var searchWrap = selection$$1.append('div')
58857 .attr('class', 'search-header');
58859 var search = searchWrap.append('input')
58860 .attr('placeholder', t('inspector.search'))
58861 .attr('type', 'search')
58862 .on('keypress', keypress)
58863 .on('input', inputevent);
58866 .call(svgIcon('#icon-search', 'pre-text'));
58868 var listWrap = selection$$1.append('div')
58869 .attr('class', 'inspector-body');
58871 var list = listWrap.append('div')
58872 .attr('class', 'feature-list cf');
58875 .on('exit.feature-list', clearSearch);
58877 .on('drawn.feature-list', mapDrawn);
58880 function keypress() {
58881 var q = search.property('value'),
58882 items = list.selectAll('.feature-list-item');
58883 if (event.keyCode === 13 && q.length && items.size()) {
58884 click(items.datum());
58889 function inputevent() {
58890 geocodeResults = undefined;
58895 function clearSearch() {
58896 search.property('value', '');
58901 function mapDrawn(e) {
58908 function features() {
58911 graph = context.graph(),
58912 q = search.property('value').toLowerCase();
58914 if (!q) return result;
58916 var idMatch = q.match(/^([nwr])([0-9]+)$/);
58921 geometry: idMatch[1] === 'n' ? 'point' : idMatch[1] === 'w' ? 'line' : 'relation',
58922 type: idMatch[1] === 'n' ? t('inspector.node') : idMatch[1] === 'w' ? t('inspector.way') : t('inspector.relation'),
58927 var locationMatch = pair_1(q.toUpperCase()) || q.match(/^(-?\d+\.?\d*)\s+(-?\d+\.?\d*)$/);
58929 if (locationMatch) {
58930 var loc = [parseFloat(locationMatch[0]), parseFloat(locationMatch[1])];
58934 type: t('inspector.location'),
58935 name: loc[0].toFixed(6) + ', ' + loc[1].toFixed(6),
58940 function addEntity(entity) {
58941 if (entity.id in entities || result.length > 200)
58944 entities[entity.id] = true;
58946 var name = utilDisplayName(entity) || '';
58947 if (name.toLowerCase().indexOf(q) >= 0) {
58948 var matched = context.presets().match(entity, graph),
58949 type = (matched && matched.name()) || utilDisplayType(entity.id);
58953 geometry: context.geometry(entity.id),
58959 graph.parentRelations(entity).forEach(function(parent) {
58964 var visible = context.surface().selectAll('.point, .line, .area').nodes();
58965 for (var i = 0; i < visible.length && result.length <= 200; i++) {
58966 addEntity(visible[i].__data__);
58969 (geocodeResults || []).forEach(function(d) {
58970 // https://github.com/openstreetmap/iD/issues/1890
58971 if (d.osm_type && d.osm_id) {
58973 id: osmEntity$$1.id.fromOSM(d.osm_type, d.osm_id),
58974 geometry: d.osm_type === 'relation' ? 'relation' : d.osm_type === 'way' ? 'line' : 'point',
58975 type: d.type !== 'yes' ? (d.type.charAt(0).toUpperCase() + d.type.slice(1)).replace('_', ' ')
58976 : (d.class.charAt(0).toUpperCase() + d.class.slice(1)).replace('_', ' '),
58977 name: d.display_name,
58978 extent: new geoExtent$$1(
58979 [parseFloat(d.boundingbox[3]), parseFloat(d.boundingbox[0])],
58980 [parseFloat(d.boundingbox[2]), parseFloat(d.boundingbox[1])])
58989 function drawList() {
58990 var value = search.property('value'),
58991 results = features();
58993 list.classed('filtered', value.length);
58995 var noResultsWorldwide = geocodeResults && geocodeResults.length === 0;
58997 var resultsIndicator = list.selectAll('.no-results-item')
58999 .enter().append('button')
59000 .property('disabled', true)
59001 .attr('class', 'no-results-item')
59002 .call(svgIcon('#icon-alert', 'pre-text'));
59004 resultsIndicator.append('span')
59005 .attr('class', 'entity-name');
59007 list.selectAll('.no-results-item .entity-name')
59008 .text(noResultsWorldwide ? t('geocoder.no_results_worldwide') : t('geocoder.no_results_visible'));
59010 list.selectAll('.geocode-item')
59012 .enter().append('button')
59013 .attr('class', 'geocode-item')
59014 .on('click', geocode)
59016 .attr('class', 'label')
59018 .attr('class', 'entity-name')
59019 .text(t('geocoder.search'));
59021 list.selectAll('.no-results-item')
59022 .style('display', (value.length && !results.length) ? 'block' : 'none');
59024 list.selectAll('.geocode-item')
59025 .style('display', (value && geocodeResults === undefined) ? 'block' : 'none');
59027 list.selectAll('.feature-list-item')
59031 var items = list.selectAll('.feature-list-item')
59032 .data(results, function(d) { return d.id; });
59034 var enter = items.enter()
59035 .insert('button', '.geocode-item')
59036 .attr('class', 'feature-list-item')
59037 .on('mouseover', mouseover)
59038 .on('mouseout', mouseout)
59039 .on('click', click);
59043 .attr('class', 'label');
59045 label.each(function(d) {
59047 .call(svgIcon('#icon-' + d.geometry, 'pre-text'));
59050 label.append('span')
59051 .attr('class', 'entity-type')
59052 .text(function(d) { return d.type; });
59054 label.append('span')
59055 .attr('class', 'entity-name')
59056 .text(function(d) { return d.name; });
59058 enter.style('opacity', 0)
59060 .style('opacity', 1);
59069 function mouseover(d) {
59070 if (d.id === -1) return;
59072 context.surface().selectAll(utilEntityOrMemberSelector([d.id], context.graph()))
59073 .classed('hover', true);
59077 function mouseout() {
59078 context.surface().selectAll('.hover')
59079 .classed('hover', false);
59083 function click(d) {
59084 event.preventDefault();
59086 context.map().centerZoom([d.location[1], d.location[0]], 20);
59088 else if (d.entity) {
59089 if (d.entity.type === 'node') {
59090 context.map().center(d.entity.loc);
59091 } else if (d.entity.type === 'way') {
59092 var center = context.projection(context.map().center()),
59093 edge = geoChooseEdge(context.childNodes(d.entity), center, context.projection);
59094 context.map().center(edge.loc);
59096 context.enter(modeSelect(context, [d.entity.id]).suppressMenu(true));
59098 context.zoomToEntity(d.id);
59103 function geocode() {
59104 var searchVal = encodeURIComponent(search.property('value'));
59105 json('https://nominatim.openstreetmap.org/search/' + searchVal + '?limit=10&format=json', function(err, resp) {
59106 geocodeResults = resp || [];
59113 return featureList;
59116 function uiPresetIcon() {
59117 var preset, geometry;
59120 function presetIcon(selection$$1) {
59121 selection$$1.each(render);
59125 function render() {
59126 var selection$$1 = select(this),
59127 p = preset.apply(this, arguments),
59128 geom = geometry.apply(this, arguments),
59129 picon = p.icon || (geom === 'line' ? 'other-line' : 'marker-stroked'),
59130 isMaki = dataFeatureIcons.hasOwnProperty(picon + '-24');
59132 if (picon === 'dentist') {
59133 isMaki = true; // workaround for dentist icon missing in `maki-sprite.json`
59136 function tag_classes(p) {
59138 for (var i in p.tags) {
59140 if (p.tags[i] !== '*') {
59141 s += ' tag-' + i + '-' + p.tags[i];
59147 var fill = selection$$1.selectAll('.preset-icon-fill')
59150 fill = fill.enter()
59155 .attr('class', function() {
59156 return 'preset-icon-fill preset-icon-fill-' + geom + tag_classes(p);
59159 var frame = selection$$1.selectAll('.preset-icon-frame')
59162 frame = frame.enter()
59164 .call(svgIcon('#preset-icon-frame'))
59168 .attr('class', function() {
59169 return 'preset-icon-frame ' + (geom === 'area' ? '' : 'hide');
59173 var icon = selection$$1.selectAll('.preset-icon')
59176 icon = icon.enter()
59178 .attr('class', 'preset-icon')
59183 .attr('class', 'preset-icon preset-icon-' + (isMaki ? '32' : (geom === 'area' ? '44' : '60')));
59185 icon.selectAll('svg')
59186 .attr('class', function() {
59187 return 'icon ' + picon + tag_classes(p);
59190 icon.selectAll('use') // workaround: maki parking-24 broken?
59191 .attr('href', '#' + picon + (isMaki ? (picon === 'parking' ? '-18' : '-24') : ''));
59195 presetIcon.preset = function(_) {
59196 if (!arguments.length) return preset;
59197 preset = utilFunctor(_);
59202 presetIcon.geometry = function(_) {
59203 if (!arguments.length) return geometry;
59204 geometry = utilFunctor(_);
59211 function d3combobox() {
59212 var event$$1 = dispatch('accept'),
59216 caseSensitive = false;
59218 var fetcher = function(val, cb) {
59219 cb(data.filter(function(d) {
59223 .indexOf(val.toLowerCase()) !== -1;
59227 var combobox = function(input, attachTo) {
59229 container = select(document.body)
59230 .selectAll('div.combobox')
59231 .filter(function(d) { return d === input.node(); }),
59232 shown = !container.empty();
59235 .classed('combobox-input', true)
59236 .on('focus.typeahead', focus)
59237 .on('blur.typeahead', blur)
59238 .on('keydown.typeahead', keydown)
59239 .on('keyup.typeahead', keyup)
59240 .on('input.typeahead', change)
59242 var parent = this.parentNode,
59243 sibling = this.nextSibling;
59245 var caret = select(parent).selectAll('.combobox-caret')
59246 .filter(function(d) { return d === input.node(); })
59247 .data([input.node()]);
59249 caret = caret.enter()
59250 .insert('div', function() { return sibling; })
59251 .attr('class', 'combobox-caret')
59255 .on('mousedown', function () {
59256 // prevent the form element from blurring. it blurs
59258 event.stopPropagation();
59259 event.preventDefault();
59261 input.node().focus();
59270 fetch(value(), render);
59274 window.setTimeout(hide, 150);
59279 container = select(document.body)
59280 .insert('div', ':first-child')
59281 .datum(input.node())
59282 .attr('class', 'combobox')
59283 .style('position', 'absolute')
59284 .style('display', 'block')
59285 .style('left', '0px')
59286 .on('mousedown', function () {
59287 // prevent moving focus out of the text field
59288 event.preventDefault();
59291 select(document.body)
59292 .on('scroll.combobox', render, true);
59301 container.remove();
59303 select(document.body)
59304 .on('scroll.combobox', null);
59310 function keydown() {
59311 switch (event.keyCode) {
59312 // backspace, delete
59315 input.on('input.typeahead', function() {
59318 var start = input.property('selectionStart');
59319 input.node().setSelectionRange(start, start);
59320 input.on('input.typeahead', change);
59325 container.selectAll('a.selected').each(function (d) {
59326 event$$1.call('accept', this, d);
59332 event.preventDefault();
59337 event.preventDefault();
59342 event.preventDefault();
59345 event.stopPropagation();
59349 switch (event.keyCode) {
59356 container.selectAll('a.selected').each(function (d) {
59357 event$$1.call('accept', this, d);
59364 function change() {
59365 fetch(value(), function() {
59366 if (input.property('selectionEnd') === input.property('value').length) {
59373 function nav(dir) {
59374 if (!suggestions.length) return;
59375 idx = Math.max(Math.min(idx + dir, suggestions.length - 1), 0);
59376 input.property('value', suggestions[idx].value);
59382 var value = input.property('value'),
59383 start = input.property('selectionStart'),
59384 end = input.property('selectionEnd');
59386 if (start && end) {
59387 value = value.substring(0, start);
59393 function fetch(v, cb) {
59394 fetcher.call(input, v, function(_) {
59400 function autocomplete() {
59401 var v = caseSensitive ? value() : value().toLowerCase();
59405 for (var i = 0; i < suggestions.length; i++) {
59406 var suggestion = suggestions[i].value,
59407 compare = caseSensitive ? suggestion : suggestion.toLowerCase();
59409 if (compare.indexOf(v) === 0) {
59411 input.property('value', suggestion);
59412 input.node().setSelectionRange(v.length, suggestion.length);
59418 function render() {
59419 if (suggestions.length >= minItems && document.activeElement === input.node()) {
59426 var options = container
59427 .selectAll('a.combobox-option')
59428 .data(suggestions, function(d) { return d.value; });
59435 .attr('class', 'combobox-option')
59436 .text(function(d) { return d.value; })
59438 .attr('title', function(d) { return d.title; })
59439 .classed('selected', function(d, i) { return i === idx; })
59440 .on('mouseover', select$$1)
59441 .on('click', accept)
59445 var node = attachTo ? attachTo.node() : input.node(),
59446 rect = node.getBoundingClientRect();
59449 .style('left', rect.left + 'px')
59450 .style('width', rect.width + 'px')
59451 .style('top', rect.height + rect.top + 'px');
59454 function select$$1(d, i) {
59459 function ensureVisible() {
59460 var node = container.selectAll('a.selected').node();
59461 if (node) node.scrollIntoView();
59464 function accept(d) {
59465 if (!shown) return;
59467 .property('value', d.value)
59468 .dispatch('change');
59469 event$$1.call('accept', this, d);
59474 combobox.fetcher = function(_) {
59475 if (!arguments.length) return fetcher;
59480 combobox.data = function(_) {
59481 if (!arguments.length) return data;
59486 combobox.minItems = function(_) {
59487 if (!arguments.length) return minItems;
59492 combobox.caseSensitive = function(_) {
59493 if (!arguments.length) return caseSensitive;
59498 return utilRebind(combobox, event$$1, 'on');
59502 d3combobox.off = function(input) {
59504 .on('focus.typeahead', null)
59505 .on('blur.typeahead', null)
59506 .on('keydown.typeahead', null)
59507 .on('keyup.typeahead', null)
59508 .on('input.typeahead', null)
59510 select(this.parentNode).selectAll('.combobox-caret')
59511 .filter(function(d) { return d === input.node(); })
59512 .on('mousedown', null);
59515 select(document.body)
59516 .on('scroll.combobox', null);
59519 function uiDisclosure() {
59520 var dispatch$$1 = dispatch('toggled'),
59523 content = function () {};
59526 var disclosure = function(selection$$1) {
59527 var hideToggle = selection$$1.selectAll('.hide-toggle')
59530 hideToggle = hideToggle.enter()
59533 .attr('class', 'hide-toggle')
59534 .merge(hideToggle);
59538 .on('click', toggle)
59539 .classed('expanded', expanded);
59542 var wrap = selection$$1.selectAll('div')
59545 wrap = wrap.enter()
59550 .classed('hide', !expanded)
59554 function toggle() {
59555 expanded = !expanded;
59556 hideToggle.classed('expanded', expanded);
59557 wrap.call(uiToggle(expanded));
59558 dispatch$$1.call('toggled', this, expanded);
59563 disclosure.title = function(_) {
59564 if (!arguments.length) return title;
59570 disclosure.expanded = function(_) {
59571 if (!arguments.length) return expanded;
59577 disclosure.content = function(_) {
59578 if (!arguments.length) return content;
59584 return utilRebind(disclosure, dispatch$$1, 'on');
59587 function uiRawMemberEditor(context) {
59589 taginfo = services.taginfo;
59592 function selectMember(d) {
59593 event.preventDefault();
59594 context.enter(modeSelect(context, [d.id]));
59598 function changeRole(d) {
59599 var role = select(this).property('value');
59600 var member = { id: d.id, type: d.type, role: role };
59602 actionChangeMember(d.relation.id, member, d.index),
59603 t('operations.change_role.annotation')
59608 function deleteMember(d) {
59610 actionDeleteMember(d.relation.id, d.index),
59611 t('operations.delete_member.annotation')
59614 if (!context.hasEntity(d.relation.id)) {
59615 context.enter(modeBrowse$$1(context));
59620 function rawMemberEditor(selection$$1) {
59621 var entity = context.entity(id),
59624 entity.members.forEach(function(member, index) {
59631 member: context.hasEntity(member.id)
59635 selection$$1.call(uiDisclosure()
59636 .title(t('inspector.all_members') + ' (' + memberships.length + ')')
59638 .on('toggled', toggled)
59643 function toggled(expanded) {
59645 selection$$1.node().parentNode.scrollTop += 200;
59650 function content(wrap) {
59651 var list = wrap.selectAll('.member-list')
59654 list = list.enter()
59656 .attr('class', 'member-list')
59660 var items = list.selectAll('li')
59661 .data(memberships, function(d) {
59662 return osmEntity$$1.key(d.relation) + ',' + d.index + ',' +
59663 (d.member ? osmEntity$$1.key(d.member) : 'incomplete');
59670 var enter = items.enter()
59672 .attr('class', 'member-row form-field')
59673 .classed('member-incomplete', function(d) { return !d.member; });
59676 .each(function(d) {
59678 var label = select(this).append('label')
59679 .attr('class', 'form-label')
59682 .on('click', selectMember);
59684 label.append('span')
59685 .attr('class', 'member-entity-type')
59686 .text(function(d) {
59687 var matched = context.presets().match(d.member, context.graph());
59688 return (matched && matched.name()) || utilDisplayType(d.member.id);
59691 label.append('span')
59692 .attr('class', 'member-entity-name')
59693 .text(function(d) { return utilDisplayName(d.member); });
59696 select(this).append('label')
59697 .attr('class', 'form-label')
59698 .text(t('inspector.incomplete', { id: d.id }));
59704 .attr('class', 'member-role')
59705 .property('type', 'text')
59706 .attr('maxlength', 255)
59707 .attr('placeholder', t('inspector.role'))
59708 .property('value', function(d) { return d.role; })
59709 .on('change', changeRole);
59713 .attr('tabindex', -1)
59714 .attr('class', 'remove button-input-action member-delete minor')
59715 .on('click', deleteMember)
59716 .call(svgIcon('#operation-delete'));
59719 enter.each(bindTypeahead);
59723 function bindTypeahead(d) {
59724 var row = select(this),
59725 role = row.selectAll('input.member-role');
59727 function sort(value, data) {
59728 var sameletter = [],
59730 for (var i = 0; i < data.length; i++) {
59731 if (data[i].value.substring(0, value.length) === value) {
59732 sameletter.push(data[i]);
59734 other.push(data[i]);
59737 return sameletter.concat(other);
59740 role.call(d3combobox()
59741 .fetcher(function(role, callback) {
59742 var rtype = entity.tags.type;
59745 rtype: rtype || '',
59746 geometry: context.geometry(d.member.id),
59748 }, function(err, data) {
59749 if (!err) callback(sort(role, data));
59755 function unbind() {
59756 var row = select(this);
59758 row.selectAll('input.member-role')
59759 .call(d3combobox.off);
59765 rawMemberEditor.entityID = function(_) {
59766 if (!arguments.length) return id;
59768 return rawMemberEditor;
59772 return rawMemberEditor;
59775 function uiRawMembershipEditor(context) {
59776 var taginfo = services.taginfo,
59780 function selectRelation(d) {
59781 event.preventDefault();
59782 context.enter(modeSelect(context, [d.relation.id]));
59786 function changeRole(d) {
59787 var role = select(this).property('value');
59789 actionChangeMember(d.relation.id, lodash.extend({}, d.member, { role: role }), d.index),
59790 t('operations.change_role.annotation')
59795 function addMembership(d, role) {
59800 actionAddMember(d.relation.id, { id: id, type: context.entity(id).type, role: role }),
59801 t('operations.add_member.annotation')
59805 var relation = osmRelation();
59807 actionAddEntity(relation),
59808 actionAddMember(relation.id, { id: id, type: context.entity(id).type, role: role }),
59809 t('operations.add.annotation.relation')
59812 context.enter(modeSelect(context, [relation.id]));
59817 function deleteMembership(d) {
59819 actionDeleteMember(d.relation.id, d.index),
59820 t('operations.delete_member.annotation')
59825 function relations(q) {
59826 var newRelation = {
59828 value: t('inspector.new_relation')
59831 graph = context.graph();
59833 context.intersects(context.extent()).forEach(function(entity) {
59834 if (entity.type !== 'relation' || entity.id === id)
59837 var matched = context.presets().match(entity, graph),
59838 presetName = (matched && matched.name()) || t('inspector.relation'),
59839 entityName = utilDisplayName(entity) || '';
59841 var value = presetName + ' ' + entityName;
59842 if (q && value.toLowerCase().indexOf(q.toLowerCase()) === -1)
59851 result.sort(function(a, b) {
59852 return osmRelation.creationOrder(a.relation, b.relation);
59855 // Dedupe identical names by appending relation id - see #2891
59856 var dupeGroups = lodash(result)
59858 .filter(function(v) { return v.length > 1; })
59861 dupeGroups.forEach(function(group) {
59862 group.forEach(function(obj) {
59863 obj.value += ' ' + obj.relation.id;
59867 result.unshift(newRelation);
59872 function rawMembershipEditor(selection$$1) {
59873 var entity = context.entity(id),
59876 context.graph().parentRelations(entity).forEach(function(relation) {
59877 relation.members.forEach(function(member, index) {
59878 if (member.id === entity.id) {
59879 memberships.push({ relation: relation, member: member, index: index });
59884 selection$$1.call(uiDisclosure()
59885 .title(t('inspector.all_relations') + ' (' + memberships.length + ')')
59887 .on('toggled', toggled)
59892 function toggled(expanded) {
59894 selection$$1.node().parentNode.scrollTop += 200;
59899 function content(wrap) {
59900 var list = wrap.selectAll('.member-list')
59903 list = list.enter()
59905 .attr('class', 'member-list')
59909 var items = list.selectAll('li.member-row-normal')
59910 .data(memberships, function(d) {
59911 return osmEntity$$1.key(d.relation) + ',' + d.index;
59918 var enter = items.enter()
59920 .attr('class', 'member-row member-row-normal form-field');
59924 .attr('class', 'form-label')
59927 .on('click', selectRelation);
59931 .attr('class', 'member-entity-type')
59932 .text(function(d) {
59933 var matched = context.presets().match(d.relation, context.graph());
59934 return (matched && matched.name()) || t('inspector.relation');
59939 .attr('class', 'member-entity-name')
59940 .text(function(d) { return utilDisplayName(d.relation); });
59944 .attr('class', 'member-role')
59945 .property('type', 'text')
59946 .attr('maxlength', 255)
59947 .attr('placeholder', t('inspector.role'))
59948 .property('value', function(d) { return d.member.role; })
59949 .on('change', changeRole);
59953 .attr('tabindex', -1)
59954 .attr('class', 'remove button-input-action member-delete minor')
59955 .on('click', deleteMembership)
59956 .call(svgIcon('#operation-delete'));
59959 enter.each(bindTypeahead);
59963 var newrow = list.selectAll('.member-row-new')
59964 .data(showBlank ? [0] : []);
59969 enter = newrow.enter()
59971 .attr('class', 'member-row member-row-new form-field');
59975 .attr('type', 'text')
59976 .attr('class', 'member-entity-input');
59980 .attr('class', 'member-role')
59981 .property('type', 'text')
59982 .attr('maxlength', 255)
59983 .attr('placeholder', t('inspector.role'))
59984 .on('change', changeRole);
59988 .attr('tabindex', -1)
59989 .attr('class', 'remove button-input-action member-delete minor')
59990 .on('click', deleteMembership)
59991 .call(svgIcon('#operation-delete'));
59996 newrow.selectAll('.member-entity-input')
59999 .fetcher(function(value, callback) { callback(relations(value)); })
60000 .on('accept', onAccept)
60004 var addrel = wrap.selectAll('.add-relation')
60007 addrel = addrel.enter()
60009 .attr('class', 'add-relation')
60013 .call(svgIcon('#icon-plus', 'light'))
60014 .on('click', function() {
60017 list.selectAll('.member-entity-input').node().focus();
60021 function onAccept(d) {
60022 var role = list.selectAll('.member-row-new .member-role').property('value');
60023 addMembership(d, role);
60027 function bindTypeahead(d) {
60028 var row = select(this),
60029 role = row.selectAll('input.member-role');
60031 function sort(value, data) {
60032 var sameletter = [],
60034 for (var i = 0; i < data.length; i++) {
60035 if (data[i].value.substring(0, value.length) === value) {
60036 sameletter.push(data[i]);
60038 other.push(data[i]);
60041 return sameletter.concat(other);
60044 role.call(d3combobox()
60045 .fetcher(function(role, callback) {
60046 var rtype = d.relation.tags.type;
60049 rtype: rtype || '',
60050 geometry: context.geometry(id),
60052 }, function(err, data) {
60053 if (!err) callback(sort(role, data));
60059 function unbind() {
60060 var row = select(this);
60062 row.selectAll('input.member-role')
60063 .call(d3combobox.off);
60069 rawMembershipEditor.entityID = function(_) {
60070 if (!arguments.length) return id;
60072 return rawMembershipEditor;
60076 return rawMembershipEditor;
60079 function uiTagReference(tag) {
60080 var taginfo = services.taginfo,
60088 function findLocal(data) {
60089 var locale = utilDetect().locale.toLowerCase(),
60092 localized = lodash.find(data, function(d) {
60093 return d.lang.toLowerCase() === locale;
60095 if (localized) return localized;
60097 // try the non-regional version of a language, like
60098 // 'en' if the language is 'en-US'
60099 if (locale.indexOf('-') !== -1) {
60100 var first = locale.split('-')[0];
60101 localized = lodash.find(data, function(d) {
60102 return d.lang.toLowerCase() === first;
60104 if (localized) return localized;
60107 // finally fall back to english
60108 return lodash.find(data, function(d) {
60109 return d.lang.toLowerCase() === 'en';
60114 function load(param) {
60115 if (!taginfo) return;
60117 button.classed('tag-reference-loading', true);
60119 taginfo.docs(param, function show(err, data) {
60121 if (!err && data) {
60122 docs = findLocal(data);
60128 if (!docs || !docs.title) {
60129 if (param.hasOwnProperty('value')) {
60130 load(lodash.omit(param, 'value')); // retry with key only
60132 body.append('p').text(t('inspector.no_documentation_key'));
60139 if (docs.image && docs.image.thumb_url_prefix) {
60142 .attr('class', 'wiki-image')
60143 .attr('src', docs.image.thumb_url_prefix + '100' + docs.image.thumb_url_suffix)
60144 .on('load', function() { done(); })
60145 .on('error', function() { select(this).remove(); done(); });
60152 .text(docs.description || t('inspector.documentation_redirect'));
60156 .attr('target', '_blank')
60157 .attr('tabindex', -1)
60158 .attr('href', 'https://wiki.openstreetmap.org/wiki/' + docs.title)
60159 .call(svgIcon('#icon-out-link', 'inline'))
60161 .text(t('inspector.reference'));
60169 button.classed('tag-reference-loading', false);
60173 .style('max-height', '200px')
60174 .style('opacity', '1');
60180 function hide(selection$$1) {
60181 selection$$1 = selection$$1 || body.transition().duration(200);
60184 .style('max-height', '0px')
60185 .style('opacity', '0');
60191 tagReference.button = function(selection$$1) {
60192 button = selection$$1.selectAll('.tag-reference-button')
60195 button = button.enter()
60197 .attr('class', 'tag-reference-button')
60198 .attr('tabindex', -1)
60199 .call(svgIcon('#icon-inspect'))
60203 .on('click', function () {
60204 event.stopPropagation();
60205 event.preventDefault();
60208 } else if (loaded) {
60217 tagReference.body = function(selection$$1) {
60218 body = selection$$1.selectAll('.tag-reference-body')
60221 body = body.enter()
60223 .attr('class', 'tag-reference-body cf')
60224 .style('max-height', '0')
60225 .style('opacity', '0')
60228 if (showing === false) {
60234 tagReference.showing = function(_) {
60235 if (!arguments.length) return showing;
60237 return tagReference;
60241 return tagReference;
60244 function uiRawTagEditor(context) {
60245 var taginfo = services.taginfo,
60246 dispatch$$1 = dispatch('change'),
60254 function rawTagEditor(selection$$1) {
60255 var count = Object.keys(tags).filter(function(d) { return d; }).length;
60257 selection$$1.call(uiDisclosure()
60258 .title(t('inspector.all_tags') + ' (' + count + ')')
60259 .expanded(context.storage('raw_tag_editor.expanded') === 'true' || preset.isFallback())
60260 .on('toggled', toggled)
60261 .content(content));
60263 function toggled(expanded) {
60264 context.storage('raw_tag_editor.expanded', expanded);
60266 selection$$1.node().parentNode.scrollTop += 200;
60272 function content(wrap) {
60273 var entries$$1 = entries(tags);
60275 if (!entries$$1.length || showBlank) {
60277 entries$$1.push({key: '', value: ''});
60280 var list = wrap.selectAll('.tag-list')
60283 list = list.enter()
60285 .attr('class', 'tag-list')
60288 var newTag = wrap.selectAll('.add-tag')
60293 .attr('class', 'add-tag')
60294 .on('click', addTag)
60295 .call(svgIcon('#icon-plus', 'light'));
60298 var items = list.selectAll('.tag-row')
60299 .data(entries$$1, function(d) { return d.key; });
60307 var enter = items.enter()
60309 .attr('class', 'tag-row cf');
60313 .attr('class', 'key-wrap')
60315 .property('type', 'text')
60316 .attr('class', 'key')
60317 .attr('maxlength', 255)
60318 .on('blur', keyChange)
60319 .on('change', keyChange);
60323 .attr('class', 'input-wrap-position')
60325 .property('type', 'text')
60326 .attr('class', 'value')
60327 .attr('maxlength', 255)
60328 .on('blur', valueChange)
60329 .on('change', valueChange)
60330 .on('keydown.push-more', pushMore);
60334 .attr('tabindex', -1)
60335 .attr('class', 'remove minor')
60336 .call(svgIcon('#operation-delete'));
60343 .sort(function(a, b) {
60344 return (a.key === '') ? 1
60345 : (b.key === '') ? -1
60346 : ascending(a.key, b.key);
60350 .each(function(tag) {
60351 var row = select(this),
60352 key = row.select('input.key'), // propagate bound data to child
60353 value = row.select('input.value'); // propagate bound data to child
60356 bindTypeahead(key, value);
60359 var isRelation = (context.entity(id).type === 'relation'),
60362 if (isRelation && tag.key === 'type') {
60363 reference = uiTagReference({ rtype: tag.value }, context);
60365 reference = uiTagReference({ key: tag.key, value: tag.value }, context);
60368 if (state === 'hover') {
60369 reference.showing(false);
60373 .call(reference.button)
60374 .call(reference.body);
60377 items.selectAll('input.key')
60378 .attr('title', function(d) { return d.key; })
60379 .call(utilGetSetValue, function(d) { return d.key; });
60381 items.selectAll('input.value')
60382 .attr('title', function(d) { return d.value; })
60383 .call(utilGetSetValue, function(d) { return d.value; });
60385 items.selectAll('button.remove')
60386 .on('click', removeTag);
60389 function pushMore() {
60390 if (event.keyCode === 9 && !event.shiftKey &&
60391 list.selectAll('li:last-child input.value').node() === this) {
60397 function bindTypeahead(key, value) {
60399 function sort(value, data) {
60400 var sameletter = [],
60402 for (var i = 0; i < data.length; i++) {
60403 if (data[i].value.substring(0, value.length) === value) {
60404 sameletter.push(data[i]);
60406 other.push(data[i]);
60409 return sameletter.concat(other);
60412 key.call(d3combobox()
60413 .fetcher(function(value, callback) {
60416 geometry: context.geometry(id),
60418 }, function(err, data) {
60419 if (!err) callback(sort(value, data));
60423 value.call(d3combobox()
60424 .fetcher(function(value, callback) {
60427 key: utilGetSetValue(key),
60428 geometry: context.geometry(id),
60430 }, function(err, data) {
60431 if (!err) callback(sort(value, data));
60437 function unbind() {
60438 var row = select(this);
60440 row.selectAll('input.key')
60441 .call(d3combobox.off);
60443 row.selectAll('input.value')
60444 .call(d3combobox.off);
60448 function keyChange(d) {
60450 kNew = this.value.trim(),
60453 if (kNew && kNew !== kOld) {
60454 var match = kNew.match(/^(.*?)(?:_(\d+))?$/),
60456 suffix = +(match[2] || 1);
60457 while (tags[kNew]) { // rename key if already in use
60458 kNew = base + '_' + suffix++;
60461 tag[kOld] = undefined;
60462 tag[kNew] = d.value;
60463 d.key = kNew; // Maintain DOM identity through the subsequent update.
60465 dispatch$$1.call('change', this, tag);
60469 function valueChange(d) {
60471 tag[d.key] = this.value;
60472 dispatch$$1.call('change', this, tag);
60476 function removeTag(d) {
60478 tag[d.key] = undefined;
60479 dispatch$$1.call('change', this, tag);
60480 select(this.parentNode).remove();
60484 function addTag() {
60485 // Wrapped in a setTimeout in case it's being called from a blur
60486 // handler. Without the setTimeout, the call to `content` would
60487 // wipe out the pending value change.
60488 setTimeout(function() {
60491 list.selectAll('li:last-child input.key').node().focus();
60497 rawTagEditor.state = function(_) {
60498 if (!arguments.length) return state;
60500 return rawTagEditor;
60504 rawTagEditor.preset = function(_) {
60505 if (!arguments.length) return preset;
60507 return rawTagEditor;
60511 rawTagEditor.tags = function(_) {
60512 if (!arguments.length) return tags;
60514 return rawTagEditor;
60518 rawTagEditor.entityID = function(_) {
60519 if (!arguments.length) return id;
60521 return rawTagEditor;
60525 return utilRebind(rawTagEditor, dispatch$$1, 'on');
60528 function uiFieldCheck(field) {
60529 var dispatch$$1 = dispatch('change'),
60530 options = field.strings && field.strings.options,
60533 box = select(null),
60534 text$$1 = select(null),
60535 label = select(null),
60539 for (var k in options) {
60540 values$$1.push(k === 'undefined' ? undefined : k);
60541 texts.push(field.t('options.' + k, { 'default': options[k] }));
60544 values$$1 = [undefined, 'yes'];
60545 texts = [t('inspector.unknown'), t('inspector.check.yes')];
60546 if (field.type === 'check') {
60547 values$$1.push('no');
60548 texts.push(t('inspector.check.no'));
60553 var check = function(selection$$1) {
60554 // hack: pretend oneway field is a oneway_yes field
60555 // where implied oneway tag exists (e.g. `junction=roundabout`) #2220, #1841
60556 if (field.id === 'oneway') {
60557 for (var key in entity.tags) {
60558 if (key in osmOneWayTags && (entity.tags[key] in osmOneWayTags[key])) {
60559 texts[0] = t('presets.fields.oneway_yes.options.undefined');
60565 selection$$1.classed('checkselect', 'true');
60567 label = selection$$1.selectAll('.preset-input-wrap')
60570 var enter = label.enter()
60572 .attr('class', 'preset-input-wrap');
60574 enter.append('input')
60575 .property('indeterminate', field.type === 'check')
60576 .attr('type', 'checkbox')
60577 .attr('id', 'preset-input-' + field.id)
60578 .on('click', function() {
60580 t$$1[field.key] = values$$1[(values$$1.indexOf(value) + 1) % values$$1.length];
60581 dispatch$$1.call('change', this, t$$1);
60582 event.stopPropagation();
60585 enter.append('span')
60587 .attr('class', 'value');
60589 label = label.merge(enter);
60591 box = label.selectAll('input');
60592 text$$1 = label.selectAll('span.value');
60596 check.entity = function(_) {
60597 if (!arguments.length) return entity;
60603 check.tags = function(tags) {
60604 value = tags[field.key];
60605 box.property('indeterminate', field.type === 'check' && !value);
60606 box.property('checked', value === 'yes');
60607 text$$1.text(texts[values$$1.indexOf(value)]);
60608 label.classed('set', !!value);
60612 check.focus = function() {
60613 box.node().focus();
60616 return utilRebind(check, dispatch$$1, 'on');
60619 function uiFieldCombo(field, context) {
60620 var dispatch$$1 = dispatch('change'),
60621 nominatim = services.nominatim,
60622 taginfo = services.taginfo,
60623 isMulti = (field.type === 'multiCombo'),
60624 isNetwork = (field.type === 'networkCombo'),
60625 optstrings = field.strings && field.strings.options,
60626 optarray = field.options,
60627 snake_case = (field.snake_case || (field.snake_case === undefined)),
60628 combobox = d3combobox().minItems(isMulti ? 1 : 2),
60636 // ensure multiCombo field.key ends with a ':'
60637 if (isMulti && field.key.match(/:$/) === null) {
60642 function snake(s) {
60643 return s.replace(/\s+/g, '_');
60646 function unsnake(s) {
60647 return s.replace(/_+/g, ' ');
60650 function clean(s) {
60651 return s.split(';')
60652 .map(function(s) { return s.trim(); })
60657 // returns the tag value for a display value
60658 // (for multiCombo, dval should be the key suffix, not the entire key)
60659 function tagValue(dval) {
60660 dval = clean(dval || '');
60663 var match = lodash.find(comboData, function(o) {
60664 return o.key && clean(o.value) === dval;
60671 if (field.type === 'typeCombo' && !dval) {
60675 return (snake_case ? snake(dval) : dval) || undefined;
60679 // returns the display value for a tag value
60680 // (for multiCombo, tval should be the key suffix, not the entire key)
60681 function displayValue(tval) {
60685 var match = lodash.find(comboData, function(o) { return o.key === tval && o.value; });
60687 return match.value;
60691 if (field.type === 'typeCombo' && tval.toLowerCase() === 'yes') {
60695 return snake_case ? unsnake(tval) : tval;
60699 function objectDifference(a, b) {
60700 return lodash.reject(a, function(d1) {
60701 return lodash.some(b, function(d2) { return d1.value === d2.value; });
60706 function initCombo(selection$$1, attachTo) {
60708 selection$$1.attr('readonly', 'readonly');
60709 selection$$1.call(combobox, attachTo);
60710 setStaticValues(setPlaceholder);
60712 } else if (optarray) {
60713 selection$$1.call(combobox, attachTo);
60714 setStaticValues(setPlaceholder);
60716 } else if (taginfo) {
60717 selection$$1.call(combobox.fetcher(setTaginfoValues), attachTo);
60718 setTaginfoValues('', setPlaceholder);
60723 function setStaticValues(callback) {
60724 if (!(optstrings || optarray)) return;
60727 comboData = Object.keys(optstrings).map(function(k) {
60728 var v = field.t('options.' + k, { 'default': optstrings[k] });
60736 } else if (optarray) {
60737 comboData = optarray.map(function(k) {
60738 var v = snake_case ? unsnake(k) : k;
60747 combobox.data(objectDifference(comboData, multiData));
60748 if (callback) callback(comboData);
60752 function setTaginfoValues(q, callback) {
60753 var fn = isMulti ? 'multikeys' : 'values';
60754 var query = (isMulti ? field.key : '') + q;
60755 var hasCountryPrefix = isNetwork && country && country.indexOf(q.toLowerCase()) === 0;
60756 if (hasCountryPrefix) {
60757 query = country + ':';
60762 geometry: context.geometry(entity.id),
60764 }, function(err, data) {
60766 if (hasCountryPrefix) {
60767 data = lodash.filter(data, function(d) {
60768 return d.value.toLowerCase().indexOf(country + ':') === 0;
60771 comboData = lodash.map(data, function(d) {
60773 if (isMulti) k = k.replace(field.key, '');
60774 var v = snake_case ? unsnake(k) : k;
60778 title: isMulti ? v : d.title
60781 comboData = objectDifference(comboData, multiData);
60782 if (callback) callback(comboData);
60787 function setPlaceholder(d) {
60790 ph = field.placeholder() || t('inspector.add');
60792 var vals = lodash.map(d, 'value').filter(function(s) { return s.length < 20; }),
60793 placeholders = vals.length > 1 ? vals : lodash.map(d, 'key');
60794 ph = field.placeholder() || placeholders.slice(0, 3).join(', ');
60797 container.selectAll('input')
60798 .attr('placeholder', ph + '…');
60802 function change() {
60803 var val = tagValue(utilGetSetValue(input)),
60808 container.classed('active', false);
60809 utilGetSetValue(input, '');
60810 field.keys.push(field.key + val);
60811 t$$1[field.key + val] = 'yes';
60812 window.setTimeout(function() { input.node().focus(); }, 10);
60815 t$$1[field.key] = val;
60818 dispatch$$1.call('change', this, t$$1);
60822 function removeMultikey(d) {
60823 event.stopPropagation();
60825 t$$1[d.key] = undefined;
60826 dispatch$$1.call('change', this, t$$1);
60830 function combo(selection$$1) {
60832 container = selection$$1.selectAll('ul').data([0]);
60834 container = container.enter()
60836 .attr('class', 'form-field-multicombo')
60837 .on('click', function() {
60838 window.setTimeout(function() { input.node().focus(); }, 10);
60843 container = selection$$1;
60846 input = container.selectAll('input')
60849 input = input.enter()
60851 .attr('type', 'text')
60852 .attr('id', 'preset-input-' + field.id)
60853 .call(initCombo, selection$$1)
60856 if (isNetwork && nominatim && entity) {
60857 var center = entity.extent(context.graph()).center();
60858 nominatim.countryCode(center, function (err, code) {
60864 .on('change', change)
60865 .on('blur', change);
60869 .on('accept', function() {
60870 input.node().blur();
60871 input.node().focus();
60875 .on('focus', function() { container.classed('active', true); });
60880 combo.tags = function(tags) {
60884 // Build multiData array containing keys already set..
60885 Object.keys(tags).forEach(function(key) {
60886 if (key.indexOf(field.key) !== 0 || tags[key].toLowerCase() !== 'yes') return;
60888 var suffix = key.substring(field.key.length);
60891 value: displayValue(suffix)
60895 // Set keys for form-field modified (needed for undo and reset buttons)..
60896 field.keys = lodash.map(multiData, 'key');
60898 // Exclude existing multikeys from combo options..
60899 var available = objectDifference(comboData, multiData);
60900 combobox.data(available);
60902 // Hide 'Add' button if this field uses fixed set of
60903 // translateable optstrings and they're all currently used..
60904 container.selectAll('.combobox-input, .combobox-caret')
60905 .classed('hide', optstrings && !available.length);
60909 var chips = container.selectAll('.chips')
60915 var enter = chips.enter()
60916 .insert('li', 'input')
60917 .attr('class', 'chips');
60919 enter.append('span');
60922 chips = chips.merge(enter);
60924 chips.select('span')
60925 .text(function(d) { return d.value; });
60928 .on('click', removeMultikey)
60929 .attr('class', 'remove')
60933 utilGetSetValue(input, displayValue(tags[field.key]));
60938 combo.focus = function() {
60939 input.node().focus();
60943 combo.entity = function(_) {
60944 if (!arguments.length) return entity;
60950 return utilRebind(combo, dispatch$$1, 'on');
60953 function uiFieldText(field, context) {
60954 var dispatch$$1 = dispatch('change'),
60955 nominatim = services.nominatim,
60960 function i(selection$$1) {
60961 var fieldId = 'preset-input-' + field.id;
60963 input = selection$$1.selectAll('input')
60966 input = input.enter()
60968 .attr('type', field.type)
60969 .attr('id', fieldId)
60970 .attr('placeholder', field.placeholder() || t('inspector.unknown'))
60974 .on('input', change(true))
60975 .on('blur', change())
60976 .on('change', change());
60978 if (field.type === 'tel' && nominatim && entity) {
60979 var center = entity.extent(context.graph()).center();
60980 nominatim.countryCode(center, function (err, countryCode) {
60981 if (err || !dataPhoneFormats[countryCode]) return;
60982 selection$$1.selectAll('#' + fieldId)
60983 .attr('placeholder', dataPhoneFormats[countryCode]);
60986 } else if (field.type === 'number') {
60987 input.attr('type', 'text');
60989 var spinControl = selection$$1.selectAll('.spin-control')
60992 var enter = spinControl.enter()
60994 .attr('class', 'spin-control');
60999 .attr('class', 'increment')
61000 .attr('tabindex', -1);
61005 .attr('class', 'decrement')
61006 .attr('tabindex', -1);
61008 spinControl = spinControl
61011 spinControl.selectAll('button')
61012 .on('click', function(d) {
61013 event.preventDefault();
61014 var num = parseInt(input.node().value || 0, 10);
61015 if (!isNaN(num)) input.node().value = num + d;
61022 function change(onInput) {
61023 return function() {
61025 t$$1[field.key] = utilGetSetValue(input) || undefined;
61026 dispatch$$1.call('change', this, t$$1, onInput);
61031 i.entity = function(_) {
61032 if (!arguments.length) return entity;
61038 i.tags = function(tags) {
61039 utilGetSetValue(input, tags[field.key] || '');
61043 i.focus = function() {
61044 var node = input.node();
61045 if (node) node.focus();
61048 return utilRebind(i, dispatch$$1, 'on');
61051 function uiFieldAccess(field) {
61052 var dispatch$$1 = dispatch('change'),
61055 function access(selection$$1) {
61056 var wrap = selection$$1.selectAll('.preset-input-wrap')
61059 wrap = wrap.enter()
61061 .attr('class', 'cf preset-input-wrap')
61065 var list = wrap.selectAll('ul')
61068 list = list.enter()
61073 items = list.selectAll('li')
61077 var enter = items.enter()
61079 .attr('class', function(d) { return 'cf preset-access-' + d; });
61083 .attr('class', 'col6 label preset-label-access')
61084 .attr('for', function(d) { return 'preset-input-access-' + d; })
61085 .text(function(d) { return field.t('types.' + d); });
61089 .attr('class', 'col6 preset-input-access-wrap')
61091 .attr('type', 'text')
61092 .attr('class', 'preset-input-access')
61093 .attr('id', function(d) { return 'preset-input-access-' + d; })
61094 .each(function(d) {
61097 .data(access.options(d)));
61102 items = items.merge(enter);
61104 wrap.selectAll('.preset-input-access')
61105 .on('change', change)
61106 .on('blur', change);
61110 function change(d) {
61112 tag[d] = utilGetSetValue(select(this)) || undefined;
61113 dispatch$$1.call('change', this, tag);
61117 access.options = function(type) {
61118 var options = ['no', 'permissive', 'private', 'destination'];
61120 if (type !== 'access') {
61121 options.unshift('yes');
61122 options.push('designated');
61124 if (type === 'bicycle') {
61125 options.push('dismount');
61129 return options.map(function(option) {
61131 title: field.t('options.' + option + '.description'),
61138 var placeholders = {
61140 foot: 'designated',
61141 motor_vehicle: 'no'
61145 motor_vehicle: 'no',
61151 motor_vehicle: 'no'
61154 motor_vehicle: 'no',
61155 bicycle: 'designated'
61158 motor_vehicle: 'no',
61159 horse: 'designated'
61163 motor_vehicle: 'no',
61169 motor_vehicle: 'yes',
61174 motor_vehicle: 'yes'
61178 motor_vehicle: 'yes',
61184 motor_vehicle: 'yes',
61190 motor_vehicle: 'yes',
61196 motor_vehicle: 'yes',
61202 motor_vehicle: 'yes',
61208 motor_vehicle: 'yes',
61214 motor_vehicle: 'yes',
61219 motor_vehicle: 'yes'
61223 motor_vehicle: 'yes',
61229 motor_vehicle: 'yes',
61235 motor_vehicle: 'yes',
61242 access.tags = function(tags) {
61243 utilGetSetValue(items.selectAll('.preset-input-access'),
61244 function(d) { return tags[d] || ''; })
61245 .attr('placeholder', function() {
61246 return tags.access ? tags.access : field.placeholder();
61249 items.selectAll('#preset-input-access-access')
61250 .attr('placeholder', 'yes');
61252 lodash.forEach(placeholders[tags.highway], function(v, k) {
61253 items.selectAll('#preset-input-access-' + k)
61254 .attr('placeholder', function() { return (tags.access || v); });
61259 access.focus = function() {
61260 items.selectAll('.preset-input-access')
61265 return utilRebind(access, dispatch$$1, 'on');
61268 function uiFieldAddress(field, context) {
61269 var dispatch$$1 = dispatch('init', 'change'),
61270 nominatim = services.nominatim,
61271 wrap = select(null),
61272 isInitialized = false,
61284 function getNearStreets() {
61285 var extent$$1 = entity.extent(context.graph()),
61286 l = extent$$1.center(),
61287 box = geoExtent$$1(l).padByMeters(200);
61289 var streets = context.intersects(box)
61290 .filter(isAddressable)
61292 var loc = context.projection([
61293 (extent$$1[0][0] + extent$$1[1][0]) / 2,
61294 (extent$$1[0][1] + extent$$1[1][1]) / 2]),
61295 choice = geoChooseEdge(context.childNodes(d), loc, context.projection);
61297 title: d.tags.name,
61298 value: d.tags.name,
61299 dist: choice.distance
61302 .sort(function(a, b) {
61303 return a.dist - b.dist;
61306 return lodash.uniqBy(streets, 'value');
61308 function isAddressable(d) {
61309 return d.tags.highway && d.tags.name && d.type === 'way';
61314 function getNearCities() {
61315 var extent$$1 = entity.extent(context.graph()),
61316 l = extent$$1.center(),
61317 box = geoExtent$$1(l).padByMeters(200);
61319 var cities = context.intersects(box)
61320 .filter(isAddressable)
61323 title: d.tags['addr:city'] || d.tags.name,
61324 value: d.tags['addr:city'] || d.tags.name,
61325 dist: geoSphericalDistance(d.extent(context.graph()).center(), l)
61328 .sort(function(a, b) {
61329 return a.dist - b.dist;
61332 return lodash.uniqBy(cities, 'value');
61335 function isAddressable(d) {
61337 (d.tags.admin_level === '8' || d.tags.border_type === 'city'))
61340 if (d.tags.place && d.tags.name && (
61341 d.tags.place === 'city' ||
61342 d.tags.place === 'town' ||
61343 d.tags.place === 'village'))
61346 if (d.tags['addr:city']) return true;
61353 function getNearValues(key) {
61354 var extent$$1 = entity.extent(context.graph()),
61355 l = extent$$1.center(),
61356 box = geoExtent$$1(l).padByMeters(200);
61358 var results = context.intersects(box)
61359 .filter(function hasTag(d) {
61360 return d.tags[key];
61364 title: d.tags[key],
61365 value: d.tags[key],
61366 dist: geoSphericalDistance(d.extent(context.graph()).center(), l)
61369 .sort(function(a, b) {
61370 return a.dist - b.dist;
61373 return lodash.uniqBy(results, 'value');
61377 function initCallback(err, countryCode) {
61380 var addressFormat = lodash.find(dataAddressFormats, function (a) {
61381 return a && a.countryCodes && lodash.includes(a.countryCodes, countryCode);
61382 }) || lodash.first(dataAddressFormats);
61385 // Normalize widths.
61386 var total = lodash.reduce(r, function(sum$$1, field) {
61387 return sum$$1 + (widths[field] || 0.5);
61390 return r.map(function (field) {
61393 width: (widths[field] || 0.5) / total
61398 wrap.selectAll('div')
61399 .data(addressFormat.format)
61402 .attr('class', 'addr-row')
61403 .selectAll('input')
61407 .property('type', 'text')
61408 .attr('placeholder', function (d) { return field.t('placeholders.' + d.id); })
61409 .attr('class', function (d) { return 'addr-' + d.id; })
61410 .style('width', function (d) { return d.width * 100 + '%'; });
61413 // setup dropdowns for common address tags
61415 'street', 'city', 'state', 'province', 'district',
61416 'subdistrict', 'suburb', 'place', 'postcode'
61419 addrTags.forEach(function(tag) {
61420 var nearValues = (tag === 'street') ? getNearStreets
61421 : (tag === 'city') ? getNearCities
61424 wrap.selectAll('.addr-' + tag)
61427 .fetcher(function(value, callback) {
61428 callback(nearValues('addr:' + tag));
61432 wrap.selectAll('input')
61433 .on('blur', change())
61434 .on('change', change());
61436 wrap.selectAll('input:not(.combobox-input)')
61437 .on('input', change(true));
61439 dispatch$$1.call('init');
61440 isInitialized = true;
61444 function address(selection$$1) {
61445 isInitialized = false;
61447 wrap = selection$$1.selectAll('.preset-input-wrap')
61450 wrap = wrap.enter()
61452 .attr('class', 'preset-input-wrap')
61456 if (nominatim && entity) {
61457 var center = entity.extent(context.graph()).center();
61458 nominatim.countryCode(center, initCallback);
61463 function change(onInput) {
61464 return function() {
61467 wrap.selectAll('input')
61468 .each(function (field) {
61469 tags['addr:' + field.id] = this.value || undefined;
61472 dispatch$$1.call('change', this, tags, onInput);
61477 function updateTags(tags) {
61478 utilGetSetValue(wrap.selectAll('input'), function (field) {
61479 return tags['addr:' + field.id] || '';
61484 address.entity = function(_) {
61485 if (!arguments.length) return entity;
61491 address.tags = function(tags) {
61492 if (isInitialized) {
61495 dispatch$$1.on('init', function () {
61502 address.focus = function() {
61503 var node = wrap.selectAll('input').node();
61504 if (node) node.focus();
61508 return utilRebind(address, dispatch$$1, 'on');
61511 function uiFieldCycleway(field) {
61512 var dispatch$$1 = dispatch('change'),
61513 items = select(null);
61516 function cycleway(selection$$1) {
61518 function stripcolon(s) {
61519 return s.replace(':', '');
61523 var wrap = selection$$1.selectAll('.preset-input-wrap')
61526 wrap = wrap.enter()
61528 .attr('class', 'cf preset-input-wrap')
61532 var div = wrap.selectAll('ul')
61540 items = div.selectAll('li')
61543 var enter = items.enter()
61545 .attr('class', function(d) { return 'cf preset-cycleway-' + stripcolon(d); });
61549 .attr('class', 'col6 label preset-label-cycleway')
61550 .attr('for', function(d) { return 'preset-input-cycleway-' + stripcolon(d); })
61551 .text(function(d) { return field.t('types.' + d); });
61555 .attr('class', 'col6 preset-input-cycleway-wrap')
61557 .attr('type', 'text')
61558 .attr('class', function(d) { return 'preset-input-cycleway preset-input-' + stripcolon(d); })
61559 .each(function(d) {
61560 select(this).call(d3combobox().data(cycleway.options(d)));
61565 wrap.selectAll('.preset-input-cycleway')
61566 .on('change', change)
61567 .on('blur', change);
61571 function change() {
61572 var left = utilGetSetValue(select('.preset-input-cyclewayleft')),
61573 right = utilGetSetValue(select('.preset-input-cyclewayright')),
61576 if (left === 'none' || left === '') { left = undefined; }
61577 if (right === 'none' || right === '') { right = undefined; }
61579 // Always set both left and right as changing one can affect the other
61581 cycleway: undefined,
61582 'cycleway:left': left,
61583 'cycleway:right': right
61586 // If the left and right tags match, use the cycleway tag to tag both
61587 // sides the same way
61588 if (left === right) {
61591 'cycleway:left': undefined,
61592 'cycleway:right': undefined
61596 dispatch$$1.call('change', this, tag);
61600 cycleway.options = function() {
61601 return keys(field.strings.options).map(function(option) {
61603 title: field.t('options.' + option + '.description'),
61610 cycleway.tags = function(tags) {
61611 utilGetSetValue(items.selectAll('.preset-input-cycleway'), function(d) {
61612 // If cycleway is set, always return that
61613 if (tags.cycleway) {
61614 return tags.cycleway;
61616 return tags[d] || '';
61618 .attr('placeholder', field.placeholder());
61622 cycleway.focus = function() {
61623 items.selectAll('.preset-input-cycleway')
61628 return utilRebind(cycleway, dispatch$$1, 'on');
61631 function uiFieldLanes(field, context) {
61632 var dispatch$$1 = dispatch('change'),
61638 function lanes(selection$$1) {
61639 lanesData = context.entity(wayID).lanes();
61641 if (!select('.inspector-wrap.inspector-hidden').empty() || !selection$$1.node().parentNode) {
61642 selection$$1.call(lanes.off);
61646 var wrap = selection$$1.selectAll('.preset-input-wrap')
61649 wrap = wrap.enter()
61651 .attr('class', 'preset-input-wrap')
61654 var surface = wrap.selectAll('.surface')
61657 var d = utilGetDimensions(wrap);
61658 var freeSpace = d[0] - lanesData.lanes.length * LANE_WIDTH * 1.5 + LANE_WIDTH * 0.5;
61660 surface = surface.enter()
61662 .attr('width', d[0])
61663 .attr('height', 300)
61664 .attr('class', 'surface')
61668 var lanesSelection = surface.selectAll('.lanes')
61671 lanesSelection = lanesSelection.enter()
61673 .attr('class', 'lanes')
61674 .merge(lanesSelection);
61677 .attr('transform', function () {
61678 return 'translate(' + (freeSpace / 2) + ', 0)';
61682 var lane = lanesSelection.selectAll('.lane')
61683 .data(lanesData.lanes);
61688 var enter = lane.enter()
61690 .attr('class', 'lane');
61696 .attr('width', LANE_WIDTH)
61697 .attr('height', LANE_HEIGHT);
61701 .attr('class', 'forward')
61709 .attr('class', 'bothways')
61717 .attr('class', 'backward')
61728 .attr('transform', function(d) {
61729 return 'translate(' + (LANE_WIDTH * d.index * 1.5) + ', 0)';
61732 lane.select('.forward')
61733 .style('visibility', function(d) {
61734 return d.direction === 'forward' ? 'visible' : 'hidden';
61737 lane.select('.bothways')
61738 .style('visibility', function(d) {
61739 return d.direction === 'bothways' ? 'visible' : 'hidden';
61742 lane.select('.backward')
61743 .style('visibility', function(d) {
61744 return d.direction === 'backward' ? 'visible' : 'hidden';
61749 lanes.entity = function(_) {
61750 if (!wayID || wayID !== _.id) {
61755 lanes.tags = function() {};
61756 lanes.focus = function() {};
61757 lanes.off = function() {};
61759 return utilRebind(lanes, dispatch$$1, 'on');
61762 function uiFieldLocalized(field, context) {
61763 var dispatch$$1 = dispatch('change', 'input'),
61764 wikipedia = services.wikipedia,
61765 input = select(null),
61766 localizedInputs = select(null),
61771 function localized(selection$$1) {
61772 input = selection$$1.selectAll('.localized-main')
61775 input = input.enter()
61777 .attr('type', 'text')
61778 .attr('id', 'preset-input-' + field.id)
61779 .attr('class', 'localized-main')
61780 .attr('placeholder', field.placeholder())
61783 if (field.id === 'name') {
61784 var preset = context.presets().match(entity, context.graph());
61785 input.call(d3combobox().fetcher(
61786 utilSuggestNames(preset, dataSuggestions)
61791 .on('input', change(true))
61792 .on('blur', change())
61793 .on('change', change());
61796 var translateButton = selection$$1.selectAll('.localized-add')
61799 translateButton = translateButton.enter()
61801 .attr('class', 'button-input-action localized-add minor')
61802 .attr('tabindex', -1)
61803 .call(svgIcon('#icon-plus'))
61805 .title(t('translate.translate'))
61806 .placement('left'))
61807 .merge(translateButton);
61810 .on('click', addNew);
61813 localizedInputs = selection$$1.selectAll('.localized-wrap')
61816 localizedInputs = localizedInputs.enter().append('div')
61817 .attr('class', 'localized-wrap')
61818 .merge(localizedInputs);
61822 function addNew() {
61823 event.preventDefault();
61824 var data$$1 = localizedInputs.selectAll('div.entry').data();
61825 var defaultLang = utilDetect().locale.toLowerCase().split('-')[0];
61826 var langExists = lodash.find(data$$1, function(datum) { return datum.lang === defaultLang;});
61827 var isLangEn = defaultLang.indexOf('en') > -1;
61828 if (isLangEn || langExists) {
61831 data$$1.push({ lang: defaultLang, value: '' });
61832 localizedInputs.call(render, data$$1);
61836 function change(onInput) {
61837 return function() {
61839 t$$1[field.key] = utilGetSetValue(select(this)) || undefined;
61840 dispatch$$1.call('change', this, t$$1, onInput);
61845 function key(lang) {
61846 return field.key + ':' + lang;
61850 function changeLang(d) {
61851 var lang = utilGetSetValue(select(this)),
61853 language = lodash.find(dataWikipedia, function(d) {
61854 return d[0].toLowerCase() === lang.toLowerCase() ||
61855 d[1].toLowerCase() === lang.toLowerCase();
61858 if (language) lang = language[2];
61860 if (d.lang && d.lang !== lang) {
61861 t$$1[key(d.lang)] = undefined;
61864 var value = utilGetSetValue(select(this.parentNode)
61865 .selectAll('.localized-value'));
61867 if (lang && value) {
61868 t$$1[key(lang)] = value;
61869 } else if (lang && wikiTitles && wikiTitles[d.lang]) {
61870 t$$1[key(lang)] = wikiTitles[d.lang];
61874 dispatch$$1.call('change', this, t$$1);
61878 function changeValue(d) {
61879 if (!d.lang) return;
61881 t$$1[key(d.lang)] = utilGetSetValue(select(this)) || undefined;
61882 dispatch$$1.call('change', this, t$$1);
61886 function fetcher(value, cb) {
61887 var v = value.toLowerCase();
61889 cb(dataWikipedia.filter(function(d) {
61890 return d[0].toLowerCase().indexOf(v) >= 0 ||
61891 d[1].toLowerCase().indexOf(v) >= 0 ||
61892 d[2].toLowerCase().indexOf(v) >= 0;
61893 }).map(function(d) {
61894 return { value: d[1] };
61899 function render(selection$$1, data$$1) {
61900 var wraps = selection$$1.selectAll('div.entry').
61901 data(data$$1, function(d) { return d.lang; });
61906 .style('max-height','0px')
61907 .style('opacity', '0')
61908 .style('top','-10px')
61911 var innerWrap = wraps.enter()
61912 .insert('div', ':first-child');
61914 innerWrap.attr('class', 'entry')
61916 var wrap = select(this);
61917 var langcombo = d3combobox().fetcher(fetcher).minItems(0);
61921 .attr('class','form-label')
61922 .text(t('translate.localized_translation_label'))
61923 .attr('for','localized-lang');
61927 .attr('class', 'minor remove')
61928 .on('click', function(d){
61929 event.preventDefault();
61931 t$$1[key(d.lang)] = undefined;
61932 dispatch$$1.call('change', this, t$$1);
61933 select(this.parentNode.parentNode)
61935 .style('max-height','240px')
61937 .style('opacity', '0')
61938 .style('max-height','0px')
61941 .call(svgIcon('#operation-delete'));
61945 .attr('class', 'localized-lang')
61946 .attr('type', 'text')
61947 .attr('placeholder',t('translate.localized_translation_language'))
61948 .on('blur', changeLang)
61949 .on('change', changeLang)
61954 .on('blur', changeValue)
61955 .on('change', changeValue)
61956 .attr('type', 'text')
61957 .attr('placeholder', t('translate.localized_translation_name'))
61958 .attr('class', 'localized-value');
61962 .style('margin-top', '0px')
61963 .style('max-height', '0px')
61964 .style('opacity', '0')
61967 .style('margin-top', '10px')
61968 .style('max-height', '240px')
61969 .style('opacity', '1')
61970 .on('end', function() {
61972 .style('max-height', '')
61973 .style('overflow', 'visible');
61977 var entry = selection$$1.selectAll('.entry');
61979 utilGetSetValue(entry.select('.localized-lang'), function(d) {
61980 var lang = lodash.find(dataWikipedia, function(lang) { return lang[2] === d.lang; });
61981 return lang ? lang[1] : d.lang;
61984 utilGetSetValue(entry.select('.localized-value'),
61985 function(d) { return d.value; });
61989 localized.tags = function(tags) {
61990 // Fetch translations from wikipedia
61991 if (tags.wikipedia && !wikiTitles) {
61993 var wm = tags.wikipedia.match(/([^:]+):(.+)/);
61994 if (wm && wm[0] && wm[1]) {
61995 wikipedia.translations(wm[1], wm[2], function(d) {
62001 utilGetSetValue(input, tags[field.key] || '');
62003 var postfixed = [], k, m;
62005 m = k.match(/^(.*):([a-zA-Z_-]+)$/);
62006 if (m && m[1] === field.key && m[2]) {
62007 postfixed.push({ lang: m[2], value: tags[k] });
62011 localizedInputs.call(render, postfixed.reverse());
62015 localized.focus = function() {
62016 input.node().focus();
62020 localized.entity = function(_) {
62021 if (!arguments.length) return entity;
62026 return utilRebind(localized, dispatch$$1, 'on');
62029 function uiFieldMaxspeed(field, context) {
62030 var dispatch$$1 = dispatch('change'),
62033 unitInput = select(null),
62034 input = select(null),
62037 var metricValues = [20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120],
62038 imperialValues = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80];
62041 function maxspeed(selection$$1) {
62042 combobox = d3combobox();
62043 var unitCombobox = d3combobox().data(['km/h', 'mph'].map(comboValues));
62045 input = selection$$1.selectAll('#preset-input-' + field.id)
62048 input = input.enter()
62050 .attr('type', 'text')
62051 .attr('id', 'preset-input-' + field.id)
62052 .attr('placeholder', field.placeholder())
62057 .on('change', change)
62058 .on('blur', change);
62060 var childNodes = context.graph().childNodes(context.entity(entity.id)),
62061 loc = childNodes[~~(childNodes.length/2)].loc;
62063 isImperial = lodash.some(dataImperial.features, function(f) {
62064 return lodash.some(f.geometry.coordinates, function(d) {
62065 return geoPointInPolygon(loc, d);
62069 unitInput = selection$$1.selectAll('input.maxspeed-unit')
62072 unitInput = unitInput.enter()
62074 .attr('type', 'text')
62075 .attr('class', 'maxspeed-unit')
62076 .call(unitCombobox)
62080 .on('blur', changeUnits)
62081 .on('change', changeUnits);
62084 function changeUnits() {
62085 isImperial = utilGetSetValue(unitInput) === 'mph';
62086 utilGetSetValue(unitInput, isImperial ? 'mph' : 'km/h');
62093 function setSuggestions() {
62094 combobox.data((isImperial ? imperialValues : metricValues).map(comboValues));
62095 utilGetSetValue(unitInput, isImperial ? 'mph' : 'km/h');
62099 function comboValues(d) {
62101 value: d.toString(),
62102 title: d.toString()
62107 function change() {
62109 value = utilGetSetValue(input);
62112 tag[field.key] = undefined;
62113 } else if (isNaN(value) || !isImperial) {
62114 tag[field.key] = value;
62116 tag[field.key] = value + ' mph';
62119 dispatch$$1.call('change', this, tag);
62123 maxspeed.tags = function(tags) {
62124 var value = tags[field.key];
62126 if (value && value.indexOf('mph') >= 0) {
62127 value = parseInt(value, 10);
62129 } else if (value) {
62130 isImperial = false;
62134 utilGetSetValue(input, value || '');
62138 maxspeed.focus = function() {
62139 input.node().focus();
62143 maxspeed.entity = function(_) {
62148 return utilRebind(maxspeed, dispatch$$1, 'on');
62151 function uiFieldRadio(field) {
62152 var dispatch$$1 = dispatch('change'),
62153 placeholder = select(null),
62154 labels = select(null),
62155 radios = select(null);
62158 function radio(selection$$1) {
62159 selection$$1.classed('preset-radio', true);
62161 var wrap = selection$$1.selectAll('.preset-input-wrap')
62164 var enter = wrap.enter()
62166 .attr('class', 'preset-input-wrap toggle-list');
62170 .attr('class', 'placeholder');
62176 placeholder = wrap.selectAll('.placeholder');
62178 labels = wrap.selectAll('label')
62179 .data(field.options || field.keys);
62181 enter = labels.enter()
62184 enter.append('input')
62185 .attr('type', 'radio')
62186 .attr('name', field.id)
62187 .attr('value', function(d) { return field.t('options.' + d, { 'default': d }); })
62188 .attr('checked', false);
62190 enter.append('span')
62191 .text(function(d) { return field.t('options.' + d, { 'default': d }); });
62196 radios = labels.selectAll('input')
62197 .on('change', change);
62201 function change() {
62203 if (field.key) t$$1[field.key] = undefined;
62204 radios.each(function(d) {
62205 var active$$1 = select(this).property('checked');
62207 if (active$$1) t$$1[field.key] = d;
62209 t$$1[d] = active$$1 ? 'yes' : undefined;
62212 dispatch$$1.call('change', this, t$$1);
62216 radio.tags = function(tags) {
62217 function checked(d) {
62219 return tags[field.key] === d;
62221 return !!(tags[d] && tags[d] !== 'no');
62225 labels.classed('active', checked);
62226 radios.property('checked', checked);
62227 var selection$$1 = radios.filter(function() { return this.checked; });
62228 if (selection$$1.empty()) {
62229 placeholder.text(t('inspector.none'));
62231 placeholder.text(selection$$1.attr('value'));
62236 radio.focus = function() {
62237 radios.node().focus();
62241 return utilRebind(radio, dispatch$$1, 'on');
62244 function uiFieldRestrictions(field, context) {
62245 var dispatch$$1 = dispatch('change'),
62246 breathe = behaviorBreathe(context),
62247 hover = behaviorHover(context),
62248 initialized = false,
62253 function restrictions(selection$$1) {
62254 // if form field is hidden or has detached from dom, clean up.
62255 if (!select('.inspector-wrap.inspector-hidden').empty() || !selection$$1.node().parentNode) {
62256 selection$$1.call(restrictions.off);
62260 var wrap = selection$$1.selectAll('.preset-input-wrap')
62263 var enter = wrap.enter()
62265 .attr('class', 'preset-input-wrap');
62269 .attr('class', 'restriction-help');
62272 var intersection = osmIntersection(context.graph(), vertexID),
62273 graph = intersection.graph,
62274 vertex = graph.entity(vertexID),
62275 filter = utilFunctor(true),
62276 extent$$1 = geoExtent$$1(),
62277 projection = geoRawMercator();
62279 var d = utilGetDimensions(wrap.merge(enter)),
62280 c = [d[0] / 2, d[1] / 2],
62284 .scale(256 * Math.pow(2, z) / (2 * Math.PI));
62286 var s = projection(vertex.loc);
62289 .translate([c[0] - s[0], c[1] - s[1]])
62290 .clipExtent([[0, 0], d]);
62292 var drawLayers = svgLayers(projection, context).only('osm').dimensions(d),
62293 drawVertices = svgVertices$$1(projection, context),
62294 drawLines = svgLines$$1(projection, context),
62295 drawTurns = svgTurns(projection, context);
62303 var surface = wrap.selectAll('.surface');
62305 if (!enter.empty()) {
62306 initialized = true;
62313 .call(utilSetDimensions, d)
62314 .call(drawVertices, graph, [vertex], filter, extent$$1, z)
62315 .call(drawLines, graph, intersection.ways, filter)
62316 .call(drawTurns, graph, intersection.turns(fromNodeID));
62319 .on('click.restrictions', click)
62320 .on('mouseover.restrictions', mouseover)
62321 .on('mouseout.restrictions', mouseout);
62324 .selectAll('.selected')
62325 .classed('selected', false);
62329 .selectAll('.' + intersection.highways[fromNodeID].id)
62330 .classed('selected', true);
62336 .on('change.restrictions', render);
62339 .on('resize.restrictions', function() {
62340 utilSetDimensions(wrap, null);
62350 var datum = event.target.__data__;
62351 if (datum instanceof osmEntity$$1) {
62352 fromNodeID = intersection.adjacentNodeId(datum.id);
62354 } else if (datum instanceof osmTurn) {
62355 if (datum.restriction) {
62357 actionUnrestrictTurn(datum, projection),
62358 t('operations.restriction.annotation.delete')
62362 actionRestrictTurn(datum, projection),
62363 t('operations.restriction.annotation.create')
62370 function mouseover() {
62371 var datum = event.target.__data__;
62372 if (datum instanceof osmTurn) {
62373 var graph = context.graph(),
62374 presets = context.presets(),
62377 if (datum.restriction) {
62378 preset = presets.match(graph.entity(datum.restriction), graph);
62380 preset = presets.item('type/restriction/' +
62381 osmInferRestriction(
62391 wrap.selectAll('.restriction-help')
62392 .text(t('operations.restriction.help.' +
62393 (datum.restriction ? 'toggle_off' : 'toggle_on'),
62394 { restriction: preset.name() })
62400 function mouseout() {
62401 wrap.selectAll('.restriction-help')
62402 .text(t('operations.restriction.help.' +
62403 (fromNodeID ? 'toggle' : 'select'))
62408 function render() {
62409 if (context.hasEntity(vertexID)) {
62410 restrictions(selection$$1);
62416 restrictions.entity = function(_) {
62417 if (!vertexID || vertexID !== _.id) {
62424 restrictions.tags = function() {};
62425 restrictions.focus = function() {};
62428 restrictions.off = function(selection$$1) {
62429 if (!initialized) return;
62431 selection$$1.selectAll('.surface')
62434 .on('click.restrictions', null)
62435 .on('mouseover.restrictions', null)
62436 .on('mouseout.restrictions', null);
62439 .on('change.restrictions', null);
62442 .on('resize.restrictions', null);
62446 return utilRebind(restrictions, dispatch$$1, 'on');
62449 function uiFieldTextarea(field) {
62450 var dispatch$$1 = dispatch('change'),
62451 input = select(null);
62454 function textarea(selection$$1) {
62455 input = selection$$1.selectAll('textarea')
62458 input = input.enter()
62459 .append('textarea')
62460 .attr('id', 'preset-input-' + field.id)
62461 .attr('placeholder', field.placeholder() || t('inspector.unknown'))
62462 .attr('maxlength', 255)
62463 .on('input', change(true))
62464 .on('blur', change())
62465 .on('change', change())
62470 function change(onInput) {
62471 return function() {
62473 t$$1[field.key] = utilGetSetValue(input) || undefined;
62474 dispatch$$1.call('change', this, t$$1, onInput);
62479 textarea.tags = function(tags) {
62480 utilGetSetValue(input, tags[field.key] || '');
62484 textarea.focus = function() {
62485 input.node().focus();
62489 return utilRebind(textarea, dispatch$$1, 'on');
62492 function uiFieldWikipedia(field, context) {
62493 var dispatch$$1 = dispatch('change'),
62494 wikipedia = services.wikipedia,
62495 wikidata = services.wikidata,
62496 link = select(null),
62497 lang = select(null),
62498 title = select(null),
62502 function wiki(selection$$1) {
62503 var langcombo = d3combobox()
62504 .fetcher(function(value, cb) {
62505 var v = value.toLowerCase();
62507 cb(dataWikipedia.filter(function(d) {
62508 return d[0].toLowerCase().indexOf(v) >= 0 ||
62509 d[1].toLowerCase().indexOf(v) >= 0 ||
62510 d[2].toLowerCase().indexOf(v) >= 0;
62511 }).map(function(d) {
62512 return { value: d[1] };
62516 var titlecombo = d3combobox()
62517 .fetcher(function(value, cb) {
62519 value = context.entity(entity.id).tags.name || '';
62522 var searchfn = value.length > 7 ? wikipedia.search : wikipedia.suggestions;
62523 searchfn(language()[2], value, function(query, data$$1) {
62524 cb(data$$1.map(function(d) {
62525 return { value: d };
62531 lang = selection$$1.selectAll('input.wiki-lang')
62534 lang = lang.enter()
62536 .attr('type', 'text')
62537 .attr('class', 'wiki-lang')
62538 .attr('placeholder', t('translate.localized_translation_language'))
62541 utilGetSetValue(lang, language()[1]);
62545 .on('blur', changeLang)
62546 .on('change', changeLang);
62549 title = selection$$1.selectAll('input.wiki-title')
62552 title = title.enter()
62554 .attr('type', 'text')
62555 .attr('class', 'wiki-title')
62556 .attr('id', 'preset-input-' + field.id)
62562 .on('change', change);
62565 link = selection$$1.selectAll('a.wiki-link')
62568 link = link.enter()
62570 .attr('class', 'wiki-link button-input-action minor')
62571 .attr('tabindex', -1)
62572 .attr('target', '_blank')
62573 .call(svgIcon('#icon-out-link', 'inline'))
62578 function language() {
62579 var value = utilGetSetValue(lang).toLowerCase();
62580 var locale = utilDetect().locale.toLowerCase();
62581 var localeLanguage;
62582 return lodash.find(dataWikipedia, function(d) {
62583 if (d[2] === locale) localeLanguage = d;
62584 return d[0].toLowerCase() === value ||
62585 d[1].toLowerCase() === value ||
62587 }) || localeLanguage || ['English', 'English', 'en'];
62591 function changeLang() {
62592 utilGetSetValue(lang, language()[1]);
62602 function change(skipWikidata) {
62603 var value = utilGetSetValue(title),
62604 m = value.match(/https?:\/\/([-a-z]+)\.wikipedia\.org\/(?:wiki|\1-[-a-z]+)\/([^#]+)(?:#(.+))?/),
62605 l = m && lodash.find(dataWikipedia, function(d) { return m[1] === d[2]; }),
62610 // Normalize title http://www.mediawiki.org/wiki/API:Query#Title_normalization
62611 value = decodeURIComponent(m[2]).replace(/_/g, ' ');
62614 // Best-effort `anchordecode:` implementation
62615 anchor = decodeURIComponent(m[3].replace(/\.([0-9A-F]{2})/g, '%$1'));
62617 anchor = decodeURIComponent(m[3]);
62619 value += '#' + anchor.replace(/_/g, ' ');
62621 value = value.slice(0, 1).toUpperCase() + value.slice(1);
62622 utilGetSetValue(lang, l[1]);
62623 utilGetSetValue(title, value);
62626 syncTags.wikipedia = value ? language()[2] + ':' + value : undefined;
62627 if (!skipWikidata) {
62628 syncTags.wikidata = undefined;
62631 dispatch$$1.call('change', this, syncTags);
62634 if (skipWikidata || !value || !language()[2]) return;
62636 // attempt asynchronous update of wikidata tag..
62637 var initEntityId = entity.id,
62638 initWikipedia = context.entity(initEntityId).tags.wikipedia;
62640 wikidata.itemsByTitle(language()[2], value, function(title, data$$1) {
62641 if (!data$$1 || !Object.keys(data$$1).length) return;
62642 var qids = Object.keys(data$$1);
62644 // 1. most recent change was a tag change
62645 var annotation = t('operations.change_tags.annotation'),
62646 currAnnotation = context.history().undoAnnotation();
62647 if (currAnnotation !== annotation) return;
62649 // 2. same entity exists and still selected
62650 var selectedIds = context.selectedIDs(),
62651 currEntityId = selectedIds.length > 0 && selectedIds[0];
62652 if (currEntityId !== initEntityId) return;
62654 // 3. wikipedia value has not changed
62655 var currTags = lodash.clone(context.entity(currEntityId).tags);
62656 if (initWikipedia !== currTags.wikipedia) return;
62658 // ok to coalesce the update of wikidata tag into the previous tag change
62659 currTags.wikidata = qids && lodash.find(qids, function(id) {
62660 return id.match(/^Q\d+$/);
62663 context.overwrite(actionChangeTags(currEntityId, currTags), annotation);
62664 dispatch$$1.call('change', this, currTags);
62669 wiki.tags = function(tags) {
62670 var value = tags[field.key] || '',
62671 m = value.match(/([^:]+):([^#]+)(?:#(.+))?/),
62672 l = m && lodash.find(dataWikipedia, function(d) { return m[1] === d[2]; }),
62673 anchor = m && m[3];
62675 // value in correct format
62677 utilGetSetValue(lang, l[1]);
62678 utilGetSetValue(title, m[2] + (anchor ? ('#' + anchor) : ''));
62681 // Best-effort `anchorencode:` implementation
62682 anchor = encodeURIComponent(anchor.replace(/ /g, '_')).replace(/%/g, '.');
62684 anchor = anchor.replace(/ /g, '_');
62687 link.attr('href', 'https://' + m[1] + '.wikipedia.org/wiki/' +
62688 m[2].replace(/ /g, '_') + (anchor ? ('#' + anchor) : ''));
62690 // unrecognized value format
62692 utilGetSetValue(title, value);
62693 if (value && value !== '') {
62694 utilGetSetValue(lang, '');
62696 link.attr('href', 'https://en.wikipedia.org/wiki/Special:Search?search=' + value);
62701 wiki.entity = function(_) {
62702 if (!arguments.length) return entity;
62708 wiki.focus = function() {
62709 title.node().focus();
62713 return utilRebind(wiki, dispatch$$1, 'on');
62717 access: uiFieldAccess,
62718 address: uiFieldAddress,
62719 check: uiFieldCheck,
62720 defaultcheck: uiFieldCheck,
62721 combo: uiFieldCombo,
62722 typeCombo: uiFieldCombo,
62723 multiCombo: uiFieldCombo,
62724 networkCombo: uiFieldCombo,
62725 cycleway: uiFieldCycleway,
62728 number: uiFieldText,
62729 email: uiFieldText,
62731 localized: uiFieldLocalized,
62732 lanes: uiFieldLanes,
62733 maxspeed: uiFieldMaxspeed,
62734 radio: uiFieldRadio,
62735 restrictions: uiFieldRestrictions,
62736 textarea: uiFieldTextarea,
62737 wikipedia: uiFieldWikipedia
62740 function uiPreset(context) {
62741 var dispatch$$1 = dispatch('change'),
62749 // Field Constructor
62750 function UIField(field, entity, show) {
62751 field = lodash.clone(field);
62753 field.input = uiFields[field.type](field, context)
62754 .on('change', function(t$$1, onInput) {
62755 dispatch$$1.call('change', field, t$$1, onInput);
62758 if (field.input.entity) field.input.entity(entity);
62760 field.keys = field.keys || [field.key];
62764 field.shown = function() {
62765 return field.id === 'name' || field.show || lodash.some(field.keys, function(key) { return !!tags[key]; });
62768 field.modified = function() {
62769 var original = context.graph().base().entities[entity.id];
62770 return lodash.some(field.keys, function(key) {
62771 return original ? tags[key] !== original.tags[key] : tags[key];
62775 field.revert = function() {
62776 var original = context.graph().base().entities[entity.id],
62778 field.keys.forEach(function(key) {
62779 t$$1[key] = original ? original.tags[key] : undefined;
62784 field.present = function() {
62785 return lodash.some(field.keys, function(key) {
62790 field.remove = function() {
62792 field.keys.forEach(function(key) {
62793 t$$1[key] = undefined;
62802 function fieldKey(field) {
62807 function presets(selection$$1) {
62808 selection$$1.call(uiDisclosure()
62809 .title(t('inspector.all_fields'))
62810 .expanded(context.storage('preset_fields.expanded') !== 'false')
62811 .on('toggled', toggled)
62815 function toggled(expanded) {
62816 context.storage('preset_fields.expanded', expanded);
62821 function content(selection$$1) {
62823 var entity = context.entity(id),
62824 geometry = context.geometry(id),
62825 presets = context.presets();
62829 if (presets.field('name')) {
62830 fieldsArr.push(UIField(presets.field('name'), entity));
62833 preset.fields.forEach(function(field) {
62834 if (field.matchGeometry(geometry)) {
62835 fieldsArr.push(UIField(field, entity, true));
62839 if (entity.isHighwayIntersection(context.graph()) && presets.field('restrictions')) {
62840 fieldsArr.push(UIField(presets.field('restrictions'), entity, true));
62843 presets.universal().forEach(function(field) {
62844 if (preset.fields.indexOf(field) < 0) {
62845 fieldsArr.push(UIField(field, entity));
62850 var shown = fieldsArr.filter(function(field) { return field.shown(); }),
62851 notShown = fieldsArr.filter(function(field) { return !field.shown(); });
62854 var form = selection$$1.selectAll('.preset-form')
62857 form = form.enter()
62859 .attr('class', 'preset-form inspector-inner fillL3')
62863 var fields = form.selectAll('.form-field')
62864 .data(shown, fieldKey);
62870 var enter = fields.enter()
62872 .attr('class', function(field) {
62873 return 'form-field form-field-' + field.id;
62878 .attr('class', 'form-label')
62879 .attr('for', function(field) { return 'preset-input-' + field.id; })
62880 .text(function(field) { return field.label(); });
62884 .attr('class', 'form-label-button-wrap');
62886 wrap.append('button')
62887 .attr('class', 'remove-icon')
62888 .attr('tabindex', -1)
62889 .call(svgIcon('#operation-delete'));
62891 wrap.append('button')
62892 .attr('class', 'modified-icon')
62893 .attr('tabindex', -1)
62895 (textDirection === 'rtl') ? svgIcon('#icon-redo') : svgIcon('#icon-undo')
62903 fields.selectAll('.form-label-button-wrap .remove-icon')
62904 .on('click', remove);
62906 fields.selectAll('.modified-icon')
62907 .on('click', revert);
62911 .classed('modified', function(field) { return field.modified(); })
62912 .classed('present', function(field) { return field.present(); })
62913 .each(function(field) {
62914 var reference = uiTagReference(field.reference || { key: field.key }, context);
62916 if (state === 'hover') {
62917 reference.showing(false);
62922 .selectAll('input')
62923 .on('keydown', function() {
62924 // if user presses enter, and combobox is not active, accept edits..
62925 if (event.keyCode === 13 && select('.combobox').empty()) {
62926 context.enter(modeBrowse$$1(context));
62929 .call(reference.body)
62930 .select('.form-label-button-wrap')
62931 .call(reference.button);
62933 field.input.tags(tags);
62936 notShown = notShown.map(function(field) {
62938 title: field.label(),
62939 value: field.label(),
62945 var more = selection$$1.selectAll('.more-fields')
62946 .data((notShown.length > 0) ? [0] : []);
62951 more = more.enter()
62953 .attr('class', 'more-fields')
62955 .text(t('inspector.add_fields'))
62959 var input = more.selectAll('.value')
62965 input = input.enter()
62967 .attr('class', 'value')
62968 .attr('type', 'text')
62972 .call(utilGetSetValue, '')
62973 .attr('placeholder', function() {
62974 var placeholder = [];
62975 for (var field in notShown) {
62976 placeholder.push(notShown[field].title);
62978 return placeholder.slice(0,3).join(', ') + ((placeholder.length > 3) ? '…' : '');
62980 .call(d3combobox().data(notShown)
62982 .on('accept', show));
62985 function show(field) {
62986 field = field.field;
62988 content(selection$$1);
62989 field.input.focus();
62993 function revert(field) {
62994 event.stopPropagation();
62995 event.preventDefault();
62996 dispatch$$1.call('change', field, field.revert());
63000 function remove(field) {
63001 event.stopPropagation();
63002 event.preventDefault();
63003 dispatch$$1.call('change', field, field.remove());
63008 presets.preset = function(_) {
63009 if (!arguments.length) return preset;
63010 if (preset && preset.id === _.id) return presets;
63017 presets.state = function(_) {
63018 if (!arguments.length) return state;
63024 presets.tags = function(_) {
63025 if (!arguments.length) return tags;
63027 // Don't reset fieldsArr here.
63032 presets.entityID = function(_) {
63033 if (!arguments.length) return id;
63034 if (id === _) return presets;
63041 return utilRebind(presets, dispatch$$1, 'on');
63044 function uiEntityEditor(context) {
63045 var dispatch$$1 = dispatch('choose'),
63047 coalesceChanges = false,
63054 var presetEditor = uiPreset(context)
63055 .on('change', changeTags);
63056 var rawTagEditor = uiRawTagEditor(context)
63057 .on('change', changeTags);
63060 function entityEditor(selection$$1) {
63061 var entity = context.entity(id),
63062 tags = lodash.clone(entity.tags);
63065 var header = selection$$1.selectAll('.header')
63069 var enter = header.enter()
63071 .attr('class', 'header fillL cf');
63075 .attr('class', 'fl preset-reset preset-choose')
63077 .html((textDirection === 'rtl') ? '►' : '◄');
63081 .attr('class', 'fr preset-close')
63082 .on('click', function() { context.enter(modeBrowse$$1(context)); })
63083 .call(svgIcon(modified ? '#icon-apply' : '#icon-close'));
63087 .text(t('inspector.edit'));
63093 header.selectAll('.preset-reset')
63094 .on('click', function() { dispatch$$1.call('choose', this, activePreset); });
63098 var body = selection$$1.selectAll('.inspector-body')
63102 enter = body.enter()
63104 .attr('class', 'inspector-body');
63108 .attr('class', 'preset-list-item inspector-inner')
63110 .attr('class', 'preset-list-button-wrap')
63112 .attr('class', 'preset-list-button preset-reset')
63113 .call(tooltip().title(t('inspector.back_tooltip')).placement('bottom'))
63115 .attr('class', 'label');
63119 .attr('class', 'inspector-border inspector-preset');
63123 .attr('class', 'inspector-border raw-tag-editor inspector-inner');
63127 .attr('class', 'inspector-border raw-member-editor inspector-inner');
63131 .attr('class', 'raw-membership-editor inspector-inner');
63137 body.selectAll('.preset-list-button-wrap')
63138 .call(reference.button);
63140 body.selectAll('.preset-list-item')
63141 .call(reference.body);
63143 body.selectAll('.preset-reset')
63144 .on('click', function() { dispatch$$1.call('choose', this, activePreset); });
63146 body.select('.preset-list-item button')
63147 .call(uiPresetIcon()
63148 .geometry(context.geometry(id))
63149 .preset(activePreset));
63151 body.select('.preset-list-item .label')
63152 .text(activePreset.name());
63154 body.select('.inspector-preset')
63156 .preset(activePreset)
63161 body.select('.raw-tag-editor')
63163 .preset(activePreset)
63168 if (entity.type === 'relation') {
63169 body.select('.raw-member-editor')
63170 .style('display', 'block')
63171 .call(uiRawMemberEditor(context)
63174 body.select('.raw-member-editor')
63175 .style('display', 'none');
63178 body.select('.raw-membership-editor')
63179 .call(uiRawMembershipEditor(context)
63184 .on('change.entity-editor', historyChanged);
63187 function historyChanged() {
63188 if (state === 'hide') return;
63190 var entity = context.hasEntity(id),
63191 graph = context.graph();
63192 if (!entity) return;
63194 entityEditor.preset(context.presets().match(entity, graph));
63195 entityEditor.modified(base !== graph);
63196 entityEditor(selection$$1);
63201 function clean(o) {
63203 function cleanVal(k, v) {
63204 function keepSpaces(k) {
63205 var whitelist = ['opening_hours', 'service_times', 'collection_times',
63206 'operating_times', 'smoking_hours', 'happy_hours'];
63207 return lodash.some(whitelist, function(s) { return k.indexOf(s) !== -1; });
63210 var blacklist = ['description', 'note', 'fixme'];
63211 if (lodash.some(blacklist, function(s) { return k.indexOf(s) !== -1; })) return v;
63213 var cleaned = v.split(';')
63214 .map(function(s) { return s.trim(); })
63215 .join(keepSpaces(k) ? '; ' : ';');
63217 // The code below is not intended to validate websites and emails.
63218 // It is only intended to prevent obvious copy-paste errors. (#2323)
63220 // clean website- and email-like tags
63221 if (k.indexOf('website') !== -1 ||
63222 k.indexOf('email') !== -1 ||
63223 cleaned.indexOf('http') === 0) {
63225 .replace(/[\u200B-\u200F\uFEFF]/g, ''); // strip LRM and other zero width chars
63232 var out = {}, k, v;
63234 if (k && (v = o[k]) !== undefined) {
63235 out[k] = cleanVal(k, v);
63242 // Tag changes that fire on input can all get coalesced into a single
63243 // history operation when the user leaves the field. #2342
63244 function changeTags(changed, onInput) {
63245 var entity = context.entity(id),
63246 annotation = t('operations.change_tags.annotation'),
63247 tags = lodash.clone(entity.tags);
63249 lodash.forEach(changed, function(v, k) {
63250 if (v !== undefined || tags.hasOwnProperty(k)) {
63256 tags = clean(tags);
63259 if (!lodash.isEqual(entity.tags, tags)) {
63260 if (coalesceChanges) {
63261 context.overwrite(actionChangeTags(id, tags), annotation);
63263 context.perform(actionChangeTags(id, tags), annotation);
63264 coalesceChanges = !!onInput;
63270 entityEditor.modified = function(_) {
63271 if (!arguments.length) return modified;
63273 selectAll('button.preset-close use')
63274 .attr('xlink:href', (modified ? '#icon-apply' : '#icon-close'));
63278 entityEditor.state = function(_) {
63279 if (!arguments.length) return state;
63281 return entityEditor;
63285 entityEditor.entityID = function(_) {
63286 if (!arguments.length) return id;
63288 base = context.graph();
63289 entityEditor.preset(context.presets().match(context.entity(id), base));
63290 entityEditor.modified(false);
63291 coalesceChanges = false;
63292 return entityEditor;
63296 entityEditor.preset = function(_) {
63297 if (!arguments.length) return activePreset;
63298 if (_ !== activePreset) {
63300 reference = uiTagReference(activePreset.reference(context.geometry(id)), context)
63303 return entityEditor;
63307 return utilRebind(entityEditor, dispatch$$1, 'on');
63310 function uiPresetList(context) {
63311 var dispatch$$1 = dispatch('choose'),
63317 function presetList(selection$$1) {
63318 var entity = context.entity(id),
63319 geometry = context.geometry(id);
63321 // Treat entities on addr:interpolation lines as points, not vertices (#3241)
63322 if (geometry === 'vertex' && entity.isOnAddressLine(context.graph())) {
63323 geometry = 'point';
63326 var presets = context.presets().matchGeometry(geometry);
63328 selection$$1.html('');
63330 var messagewrap = selection$$1
63332 .attr('class', 'header fillL cf');
63334 var message = messagewrap
63336 .text(t('inspector.choose'));
63338 if (context.entity(id).isUsed(context.graph())) {
63341 .attr('class', 'preset-choose')
63342 .on('click', function() { dispatch$$1.call('choose', this, currentPreset); })
63344 .html((textDirection === 'rtl') ? '◄' : '►');
63348 .attr('class', 'close')
63349 .on('click', function() {
63350 context.enter(modeBrowse$$1(context));
63352 .call(svgIcon('#icon-close'));
63355 function keydown() {
63356 // hack to let delete shortcut work when search is autofocused
63357 if (search.property('value').length === 0 &&
63358 (event.keyCode === d3keybinding.keyCodes['⌫'] ||
63359 event.keyCode === d3keybinding.keyCodes['⌦'])) {
63360 event.preventDefault();
63361 event.stopPropagation();
63362 operationDelete([id], context)();
63363 } else if (search.property('value').length === 0 &&
63364 (event.ctrlKey || event.metaKey) &&
63365 event.keyCode === d3keybinding.keyCodes.z) {
63366 event.preventDefault();
63367 event.stopPropagation();
63369 } else if (!event.ctrlKey && !event.metaKey) {
63370 select(this).on('keydown', null);
63374 function keypress() {
63376 var value = search.property('value');
63377 if (event.keyCode === 13 && value.length) {
63378 list.selectAll('.preset-list-item:first-child').datum().choose();
63382 function inputevent() {
63383 var value = search.property('value');
63384 list.classed('filtered', value.length);
63385 if (value.length) {
63386 var results = presets.search(value, geometry);
63387 message.text(t('inspector.results', {
63388 n: results.collection.length,
63391 list.call(drawList, results);
63393 list.call(drawList, context.presets().defaults(geometry, 36));
63394 message.text(t('inspector.choose'));
63398 var searchWrap = selection$$1
63400 .attr('class', 'search-header');
63402 var search = searchWrap
63404 .attr('class', 'preset-search-input')
63405 .attr('placeholder', t('inspector.search'))
63406 .attr('type', 'search')
63407 .on('keydown', keydown)
63408 .on('keypress', keypress)
63409 .on('input', inputevent);
63412 .call(svgIcon('#icon-search', 'pre-text'));
63415 search.node().focus();
63418 var listWrap = selection$$1
63420 .attr('class', 'inspector-body');
63422 var list = listWrap
63424 .attr('class', 'preset-list fillL cf')
63425 .call(drawList, context.presets().defaults(geometry, 36));
63429 function drawList(list, presets) {
63430 var collection = presets.collection.map(function(preset) {
63431 return preset.members ? CategoryItem(preset) : PresetItem(preset);
63434 var items = list.selectAll('.preset-list-item')
63435 .data(collection, function(d) { return d.preset.id; });
63444 .attr('class', function(item) { return 'preset-list-item preset-' + item.preset.id.replace('/', '-'); })
63445 .classed('current', function(item) { return item.preset === currentPreset; })
63446 .each(function(item) { select(this).call(item); })
63447 .style('opacity', 0)
63449 .style('opacity', 1);
63453 function CategoryItem(preset) {
63454 var box, sublist, shown = false;
63456 function item(selection$$1) {
63457 var wrap = selection$$1.append('div')
63458 .attr('class', 'preset-list-button-wrap category col12');
63460 wrap.append('button')
63461 .attr('class', 'preset-list-button')
63462 .classed('expanded', false)
63463 .call(uiPresetIcon()
63464 .geometry(context.geometry(id))
63466 .on('click', function() {
63467 var isExpanded = select(this).classed('expanded');
63468 var triangle = isExpanded ? '▶ ' : '▼ ';
63469 select(this).classed('expanded', !isExpanded);
63470 select(this).selectAll('.label').text(triangle + preset.name());
63474 .attr('class', 'label')
63476 return '▶ ' + preset.name();
63479 box = selection$$1.append('div')
63480 .attr('class', 'subgrid col12')
63481 .style('max-height', '0px')
63482 .style('opacity', 0);
63485 .attr('class', 'arrow');
63487 sublist = box.append('div')
63488 .attr('class', 'preset-list fillL3 cf fl');
63491 item.choose = function() {
63492 if (!box || !sublist) return;
63498 .style('opacity', '0')
63499 .style('max-height', '0px')
63500 .style('padding-bottom', '0px');
63503 sublist.call(drawList, preset.members);
63506 .style('opacity', '1')
63507 .style('max-height', 200 + preset.members.collection.length * 80 + 'px')
63508 .style('padding-bottom', '20px');
63512 item.preset = preset;
63518 function PresetItem(preset) {
63519 function item(selection$$1) {
63520 var wrap = selection$$1.append('div')
63521 .attr('class', 'preset-list-button-wrap col12');
63523 wrap.append('button')
63524 .attr('class', 'preset-list-button')
63525 .call(uiPresetIcon()
63526 .geometry(context.geometry(id))
63528 .on('click', item.choose)
63530 .attr('class', 'label')
63531 .text(preset.name());
63533 wrap.call(item.reference.button);
63534 selection$$1.call(item.reference.body);
63537 item.choose = function() {
63538 context.presets().choose(preset);
63541 actionChangePreset(id, currentPreset, preset),
63542 t('operations.change_tags.annotation')
63545 dispatch$$1.call('choose', this, preset);
63548 item.help = function() {
63549 event.stopPropagation();
63550 item.reference.toggle();
63553 item.preset = preset;
63554 item.reference = uiTagReference(preset.reference(context.geometry(id)), context);
63560 presetList.autofocus = function(_) {
63561 if (!arguments.length) return autofocus;
63567 presetList.entityID = function(_) {
63568 if (!arguments.length) return id;
63570 presetList.preset(context.presets().match(context.entity(id), context.graph()));
63575 presetList.preset = function(_) {
63576 if (!arguments.length) return currentPreset;
63582 return utilRebind(presetList, dispatch$$1, 'on');
63585 function uiViewOnOSM(context) {
63588 function viewOnOSM(selection) {
63589 var entity = context.entity(id);
63591 selection.style('display', entity.isNew() ? 'none' : null);
63593 var link = selection.selectAll('.view-on-osm')
63598 .attr('class', 'view-on-osm')
63599 .attr('target', '_blank')
63600 .call(svgIcon('#icon-out-link', 'inline'))
63602 .text(t('inspector.view_on_osm'));
63605 .attr('href', context.connection().entityURL(entity));
63609 viewOnOSM.entityID = function(_) {
63610 if (!arguments.length) return id;
63618 function uiInspector(context) {
63619 var presetList = uiPresetList(context),
63620 entityEditor = uiEntityEditor(context),
63623 newFeature = false;
63626 function inspector(selection$$1) {
63628 .entityID(entityID)
63629 .autofocus(newFeature)
63630 .on('choose', setPreset);
63634 .entityID(entityID)
63635 .on('choose', showList);
63637 var wrap = selection$$1.selectAll('.panewrap')
63640 var enter = wrap.enter()
63642 .attr('class', 'panewrap');
63646 .attr('class', 'preset-list-pane pane');
63650 .attr('class', 'entity-editor-pane pane');
63652 wrap = wrap.merge(enter);
63653 var presetPane = wrap.selectAll('.preset-list-pane');
63654 var editorPane = wrap.selectAll('.entity-editor-pane');
63656 var graph = context.graph(),
63657 entity = context.entity(entityID),
63658 showEditor = state === 'hover' ||
63659 entity.isUsed(graph) ||
63660 entity.isHighwayIntersection(graph);
63663 wrap.style('right', '0%');
63664 editorPane.call(entityEditor);
63666 wrap.style('right', '-100%');
63667 presetPane.call(presetList);
63670 var footer = selection$$1.selectAll('.footer')
63673 footer = footer.enter()
63675 .attr('class', 'footer')
63679 .call(uiViewOnOSM(context).entityID(entityID));
63682 function showList(preset) {
63684 .styleTween('right', function() { return interpolate('0%', '-100%'); });
63687 .call(presetList.preset(preset).autofocus(true));
63691 function setPreset(preset) {
63693 .styleTween('right', function() { return interpolate('-100%', '0%'); });
63696 .call(entityEditor.preset(preset));
63701 inspector.state = function(_) {
63702 if (!arguments.length) return state;
63704 entityEditor.state(state);
63709 inspector.entityID = function(_) {
63710 if (!arguments.length) return entityID;
63716 inspector.newFeature = function(_) {
63717 if (!arguments.length) return newFeature;
63726 function uiNotice(context) {
63728 return function(selection) {
63729 var div = selection
63731 .attr('class', 'notice');
63735 .attr('class', 'zoom-to notice')
63736 .on('click', function() { context.map().zoom(context.minEditableZoom()); });
63739 .call(svgIcon('#icon-plus', 'pre-text'))
63741 .attr('class', 'label')
63742 .text(t('zoom_in_edit'));
63745 function disableTooHigh() {
63746 div.style('display', context.editable() ? 'none' : 'block');
63750 .on('move.notice', lodash.debounce(disableTooHigh, 500));
63756 function uiSidebar(context) {
63757 var inspector = uiInspector(context),
63761 function sidebar(selection) {
63762 var featureListWrap = selection
63764 .attr('class', 'feature-list-pane')
63765 .call(uiFeatureList(context));
63768 .call(uiNotice(context));
63770 var inspectorWrap = selection
63772 .attr('class', 'inspector-hidden inspector-wrap fr');
63775 function hover(id) {
63776 if (!current && context.hasEntity(id)) {
63778 .classed('inspector-hidden', true);
63781 .classed('inspector-hidden', false)
63782 .classed('inspector-hover', true);
63784 if (inspector.entityID() !== id || inspector.state() !== 'hover') {
63793 } else if (!current) {
63795 .classed('inspector-hidden', false);
63797 .classed('inspector-hidden', true);
63804 sidebar.hover = lodash.throttle(hover, 200);
63807 sidebar.select = function(id, newFeature) {
63808 if (!current && id) {
63810 .classed('inspector-hidden', true);
63813 .classed('inspector-hidden', false)
63814 .classed('inspector-hover', false);
63816 if (inspector.entityID() !== id || inspector.state() !== 'select') {
63820 .newFeature(newFeature);
63826 } else if (!current) {
63828 .classed('inspector-hidden', false);
63830 .classed('inspector-hidden', true);
63837 sidebar.show = function(component) {
63839 .classed('inspector-hidden', true);
63841 .classed('inspector-hidden', true);
63843 if (current) current.remove();
63844 current = selection
63846 .attr('class', 'sidebar-component')
63851 sidebar.hide = function() {
63853 .classed('inspector-hidden', false);
63855 .classed('inspector-hidden', true);
63857 if (current) current.remove();
63863 sidebar.hover = function() {};
63864 sidebar.hover.cancel = function() {};
63865 sidebar.select = function() {};
63866 sidebar.show = function() {};
63867 sidebar.hide = function() {};
63872 function uiSpinner(context) {
63873 var connection = context.connection();
63876 return function(selection) {
63877 var img = selection
63879 .attr('src', context.imagePath('loader-black.gif'))
63880 .style('opacity', 0);
63883 .on('loading.spinner', function() {
63885 .style('opacity', 1);
63889 .on('loaded.spinner', function() {
63891 .style('opacity', 0);
63896 function uiSplash(context) {
63898 return function(selection$$1) {
63899 if (context.storage('sawSplash'))
63902 context.storage('sawSplash', true);
63904 var modalSelection = uiModal(selection$$1);
63906 modalSelection.select('.modal')
63907 .attr('class', 'modal-splash modal col6');
63909 var introModal = modalSelection.select('.content')
63911 .attr('class', 'fillL');
63915 .attr('class','modal-section cf')
63916 .append('h3').text(t('splash.welcome'));
63920 .attr('class','modal-section')
63922 .html(t('splash.text', {
63923 version: context.version,
63924 website: '<a href="http://ideditor.com/">ideditor.com</a>',
63925 github: '<a href="https://github.com/openstreetmap/iD">github.com</a>'
63928 var buttons = introModal
63930 .attr('class', 'modal-actions cf');
63934 .attr('class', 'col6 walkthrough')
63935 .text(t('splash.walkthrough'))
63936 .on('click', function() {
63937 select(document.body).call(uiIntro(context));
63938 modalSelection.close();
63943 .attr('class', 'col6 start')
63944 .text(t('splash.start'))
63945 .on('click', modalSelection.close);
63947 modalSelection.select('button.close')
63948 .attr('class','hide');
63953 function uiStatus(context) {
63954 var connection = context.connection();
63956 return function(selection$$1) {
63958 function update() {
63959 connection.status(function(err, apiStatus) {
63960 selection$$1.html('');
63963 if (apiStatus === 'rateLimited') {
63965 .text(t('status.rateLimit'))
63967 .attr('class', 'api-status-login')
63968 .attr('target', '_blank')
63969 .call(svgIcon('#icon-out-link', 'inline'))
63972 .on('click.login', function() {
63973 event.preventDefault();
63974 connection.authenticate();
63977 // TODO: nice messages for different error types
63978 selection$$1.text(t('status.error'));
63981 } else if (apiStatus === 'readonly') {
63982 selection$$1.text(t('status.readonly'));
63983 } else if (apiStatus === 'offline') {
63984 selection$$1.text(t('status.offline'));
63987 selection$$1.attr('class', 'api-status ' + (err ? 'error' : apiStatus));
63992 .on('change', function() { update(selection$$1); });
63994 window.setInterval(update, 90000);
63995 update(selection$$1);
63999 function uiUndoRedo(context) {
64003 action: function() { if (!(context.inIntro() || saving())) context.undo(); },
64004 annotation: function() { return context.history().undoAnnotation(); }
64008 action: function() {if (!(context.inIntro() || saving())) context.redo(); },
64009 annotation: function() { return context.history().redoAnnotation(); }
64013 function saving() {
64014 return context.mode().id === 'save';
64018 return function(selection$$1) {
64019 var tooltipBehavior = tooltip()
64020 .placement('bottom')
64022 .title(function (d) {
64023 return uiTooltipHtml(d.annotation() ?
64024 t(d.id + '.tooltip', {action: d.annotation()}) :
64025 t(d.id + '.nothing'), d.cmd);
64028 var buttons = selection$$1.selectAll('button')
64032 .attr('class', 'col6 disabled')
64033 .on('click', function(d) { return d.action(); })
64034 .call(tooltipBehavior);
64036 buttons.each(function(d) {
64037 var iconName = d.id;
64038 if (textDirection === 'rtl') {
64039 if (iconName === 'undo') {
64041 } else if (iconName === 'redo') {
64046 .call(svgIcon('#icon-' + iconName));
64049 var keybinding = d3keybinding('undo')
64050 .on(commands[0].cmd, function() { event.preventDefault(); commands[0].action(); })
64051 .on(commands[1].cmd, function() { event.preventDefault(); commands[1].action(); });
64057 .on('change.undo_redo', update);
64060 .on('enter.undo_redo', update);
64062 function update() {
64064 .property('disabled', saving())
64065 .classed('disabled', function(d) { return !d.annotation(); })
64067 var selection$$1 = select(this);
64068 if (selection$$1.property('tooltipVisible')) {
64069 selection$$1.call(tooltipBehavior.show);
64076 function uiZoom(context) {
64080 title: t('zoom.in'),
64081 action: context.zoomIn,
64086 title: t('zoom.out'),
64087 action: context.zoomOut,
64092 function zoomIn() {
64093 event.preventDefault();
64094 if (!context.inIntro()) context.zoomIn();
64098 function zoomOut() {
64099 event.preventDefault();
64100 if (!context.inIntro()) context.zoomOut();
64104 function zoomInFurther() {
64105 event.preventDefault();
64106 if (!context.inIntro()) context.zoomInFurther();
64110 function zoomOutFurther() {
64111 event.preventDefault();
64112 if (!context.inIntro()) context.zoomOutFurther();
64116 return function(selection$$1) {
64117 var button = selection$$1.selectAll('button')
64121 .attr('tabindex', -1)
64122 .attr('class', function(d) { return d.id; })
64123 .on('click.editor', function(d) { d.action(); })
64125 .placement((textDirection === 'rtl') ? 'right' : 'left')
64127 .title(function(d) {
64128 return uiTooltipHtml(d.title, d.key);
64132 button.each(function(d) {
64134 .call(svgIcon('#icon-' + d.icon, 'light'));
64137 var keybinding = d3keybinding('zoom');
64139 lodash.each(['=','ffequals','plus','ffplus'], function(key) {
64140 keybinding.on([key, '⇧' + key], zoomIn);
64141 keybinding.on([uiCmd('⌘' + key), uiCmd('⌘⇧' + key)], zoomInFurther);
64143 lodash.each(['-','ffminus','dash'], function(key) {
64144 keybinding.on([key, '⇧' + key], zoomOut);
64145 keybinding.on([uiCmd('⌘' + key), uiCmd('⌘⇧' + key)], zoomOutFurther);
64153 function uiInit(context) {
64155 function render(container) {
64156 var map$$1 = context.map();
64158 var hash = behaviorHash(context);
64161 if (!hash.hadHash) {
64162 map$$1.centerZoom([0, 0], 2);
64167 .attr('id', 'defs')
64168 .call(svgDefs(context));
64172 .attr('id', 'sidebar')
64173 .attr('class', 'col4')
64176 var content = container
64178 .attr('id', 'content');
64183 .attr('class', 'fillD');
64188 .attr('dir', 'ltr')
64191 if (textDirection === 'rtl') {
64192 select('body').attr('dir', 'rtl');
64196 .call(uiMapInMap(context));
64200 .call(uiInfo(context));
64204 .attr('class', 'spacer col4');
64206 var limiter = bar.append('div')
64207 .attr('class', 'limiter');
64211 .attr('class', 'button-wrap joined col3')
64212 .call(uiModes(context), limiter);
64216 .attr('class', 'button-wrap joined col1')
64217 .call(uiUndoRedo(context));
64221 .attr('class', 'button-wrap col1')
64222 .call(uiSave(context));
64226 .attr('class', 'full-screen')
64227 .call(uiFullScreen(context));
64231 .attr('class', 'spinner')
64232 .call(uiSpinner(context));
64236 .attr('class', 'map-controls');
64240 .attr('class', 'map-control zoombuttons')
64241 .call(uiZoom(context));
64245 .attr('class', 'map-control geolocate-control')
64246 .call(uiGeolocate(context));
64250 .attr('class', 'map-control background-control')
64251 .call(uiBackground(context));
64255 .attr('class', 'map-control map-data-control')
64256 .call(uiMapData(context));
64260 .attr('class', 'map-control help-control')
64261 .call(uiHelp(context));
64263 var about = content
64265 .attr('id', 'about');
64269 .attr('id', 'attrib')
64270 .attr('dir', 'ltr')
64271 .call(uiAttribution(context));
64275 .attr('id', 'footer')
64276 .attr('class', 'fillD');
64280 .attr('class', 'api-status')
64281 .call(uiStatus(context));
64285 .attr('id', 'scale-block')
64286 .call(uiScale(context));
64288 var aboutList = footer
64290 .attr('id', 'info-block')
64292 .attr('id', 'about-list');
64294 if (!context.embed()) {
64295 aboutList.call(uiAccount(context));
64301 .attr('target', '_blank')
64302 .attr('tabindex', -1)
64303 .attr('href', 'https://github.com/openstreetmap/iD')
64304 .text(context.version);
64306 var issueLinks = aboutList
64311 .attr('target', '_blank')
64312 .attr('tabindex', -1)
64313 .attr('href', 'https://github.com/openstreetmap/iD/issues')
64314 .call(svgIcon('#icon-bug', 'light'))
64315 .call(tooltip().title(t('report_a_bug')).placement('top'));
64319 .attr('target', '_blank')
64320 .attr('tabindex', -1)
64321 .attr('href', 'https://github.com/openstreetmap/iD/blob/master/CONTRIBUTING.md#translating')
64322 .call(svgIcon('#icon-translate', 'light'))
64323 .call(tooltip().title(t('help_translate')).placement('top'));
64327 .attr('class', 'feature-warning')
64328 .attr('tabindex', -1)
64329 .call(uiFeatureInfo(context));
64333 .attr('class', 'user-list')
64334 .attr('tabindex', -1)
64335 .call(uiContributors(context));
64338 window.onbeforeunload = function() {
64339 return context.save();
64342 window.onunload = function() {
64343 context.history().unlock();
64346 var mapDimensions = map$$1.dimensions();
64348 function onResize() {
64349 mapDimensions = utilGetDimensions(content, true);
64350 map$$1.dimensions(mapDimensions);
64354 .on('resize.editor', onResize);
64359 return function() {
64360 event.preventDefault();
64361 if (!context.inIntro()) {
64362 context.pan(d, 100);
64370 var keybinding = d3keybinding('main')
64371 .on('⌫', function() { event.preventDefault(); })
64372 .on('←', pan([pa, 0]))
64373 .on('↑', pan([0, pa]))
64374 .on('→', pan([-pa, 0]))
64375 .on('↓', pan([0, -pa]))
64376 .on(['⇧←', uiCmd('⌘←')], pan([mapDimensions[0], 0]))
64377 .on(['⇧↑', uiCmd('⌘↑')], pan([0, mapDimensions[1]]))
64378 .on(['⇧→', uiCmd('⌘→')], pan([-mapDimensions[0], 0]))
64379 .on(['⇧↓', uiCmd('⌘↓')], pan([0, -mapDimensions[1]]));
64384 context.enter(modeBrowse$$1(context));
64386 context.container()
64387 .call(uiSplash(context))
64388 .call(uiRestore(context));
64390 var authenticating = uiLoading(context)
64391 .message(t('loading_auth'))
64394 context.connection()
64395 .on('authLoading.ui', function() {
64396 context.container()
64397 .call(authenticating);
64399 .on('authDone.ui', function() {
64400 authenticating.close();
64405 function ui(node, callback) {
64406 var container = select(node);
64407 context.container(container);
64408 context.loadLocale(function(err) {
64418 ui.sidebar = uiSidebar(context);
64423 function uiCommit(context) {
64424 var dispatch$$1 = dispatch('cancel', 'save');
64427 function commit(selection$$1) {
64428 var changes = context.history().changes(),
64429 summary = context.history().difference().summary();
64433 .attr('class', 'header fillL')
64435 .text(t('commit.title'));
64437 var body = selection$$1
64439 .attr('class', 'body');
64441 var commentSection = body
64443 .attr('class', 'modal-section form-field commit-form');
64447 .attr('class', 'form-label')
64448 .text(t('commit.message_label'));
64450 var commentField = commentSection
64451 .append('textarea')
64452 .attr('placeholder', t('commit.description_placeholder'))
64453 .attr('maxlength', 255)
64454 .property('value', context.storage('comment') || '')
64455 .on('input.save', checkComment)
64456 .on('change.save', checkComment)
64457 .on('blur.save', function() {
64458 context.storage('comment', this.value);
64462 commentField.node().select();
64464 context.connection().userChangesets(function (err, changesets) {
64469 for (var i = 0; i < changesets.length; i++) {
64470 if (changesets[i].tags.comment) {
64472 title: changesets[i].tags.comment,
64473 value: changesets[i].tags.comment
64479 .call(d3combobox().caseSensitive(true).data(comments));
64482 var clippyArea = commentSection.append('div')
64483 .attr('class', 'clippy-area');
64485 var changeSetInfo = commentSection.append('div')
64486 .attr('class', 'changeset-info');
64488 changeSetInfo.append('a')
64489 .attr('target', '_blank')
64490 .attr('tabindex', -1)
64491 .call(svgIcon('#icon-out-link', 'inline'))
64492 .attr('href', t('commit.about_changeset_comments_link'))
64494 .text(t('commit.about_changeset_comments'));
64498 var warnings = body.selectAll('div.warning-section')
64499 .data([context.history().validate(changes)]);
64501 warnings = warnings.enter()
64503 .attr('class', 'modal-section warning-section fillL2')
64504 .style('display', function(d) { return lodash.isEmpty(d) ? 'none' : null; })
64505 .style('background', '#ffb')
64510 .text(t('commit.warnings'));
64514 .attr('class', 'changeset-list');
64516 var warningLi = warnings.select('ul').selectAll('li')
64517 .data(function(d) { return d; });
64519 warningLi = warningLi.enter()
64521 .on('mouseover', mouseover)
64522 .on('mouseout', mouseout)
64523 .on('click', warningClick)
64527 .call(svgIcon('#icon-alert', 'pre-text'));
64531 .text(function(d) { return d.message; });
64533 warningLi.filter(function(d) { return d.tooltip; })
64535 .title(function(d) { return d.tooltip; })
64540 // Upload Explanation
64541 var saveSection = body
64543 .attr('class','modal-section save-section fillL cf');
64545 var prose = saveSection
64547 .attr('class', 'commit-info')
64548 .html(t('commit.upload_explanation'));
64551 context.connection().userDetails(function(err, user) {
64554 var userLink = select(document.createElement('div'));
64556 if (user.image_url) {
64559 .attr('src', user.image_url)
64560 .attr('class', 'icon pre-text user-icon');
64565 .attr('class','user-info')
64566 .text(user.display_name)
64567 .attr('href', context.connection().userURL(user.display_name))
64568 .attr('tabindex', -1)
64569 .attr('target', '_blank');
64572 .html(t('commit.upload_explanation_with_user', { user: userLink.html() }));
64577 var buttonSection = saveSection
64579 .attr('class','buttons fillL cf');
64581 var cancelButton = buttonSection
64583 .attr('class', 'secondary-action col5 button cancel-button')
64584 .on('click.cancel', function() { dispatch$$1.call('cancel'); });
64588 .attr('class', 'label')
64589 .text(t('commit.cancel'));
64591 var saveButton = buttonSection
64593 .attr('class', 'action col5 button save-button')
64594 .attr('disabled', function() {
64595 var n = select('.commit-form textarea').node();
64596 return (n && n.value.length) ? null : true;
64598 .on('click.save', function() {
64599 dispatch$$1.call('save', this, {
64600 comment: commentField.node().value
64606 .attr('class', 'label')
64607 .text(t('commit.save'));
64611 var changeSection = body
64613 .attr('class', 'commit-section modal-section fillL2');
64615 changeSection.append('h3')
64616 .text(t('commit.changes', { count: summary.length }));
64618 var li = changeSection
64620 .attr('class', 'changeset-list')
64626 .on('mouseover', mouseover)
64627 .on('mouseout', mouseout)
64628 .on('click', zoomToEntity)
64631 li.each(function(d) {
64633 .call(svgIcon('#icon-' + d.entity.geometry(d.graph), 'pre-text ' + d.changeType));
64637 .attr('class', 'change-type')
64638 .text(function(d) { return t('commit.' + d.changeType) + ' '; });
64640 li.append('strong')
64641 .attr('class', 'entity-type')
64642 .text(function(d) {
64643 var matched = context.presets().match(d.entity, d.graph);
64644 return (matched && matched.name()) || utilDisplayType(d.entity.id);
64648 .attr('class', 'entity-name')
64649 .text(function(d) {
64650 var name = utilDisplayName(d.entity) || '',
64652 if (name !== '') string += ':';
64653 return string += ' ' + name;
64656 li.style('opacity', 0)
64658 .style('opacity', 1);
64661 // Call checkComment off the bat, in case a changeset
64662 // comment is recovered from localStorage
64663 utilTriggerEvent(commentField, 'input');
64666 function mouseover(d) {
64668 context.surface().selectAll(
64669 utilEntityOrMemberSelector([d.entity.id], context.graph())
64670 ).classed('hover', true);
64675 function mouseout() {
64676 context.surface().selectAll('.hover')
64677 .classed('hover', false);
64681 function warningClick(d) {
64683 context.map().zoomTo(d.entity);
64685 modeSelect(context, [d.entity.id]).suppressMenu(true)
64691 function zoomToEntity(change) {
64692 var entity = change.entity;
64693 if (change.changeType !== 'deleted' &&
64694 context.graph().entity(entity.id).geometry(context.graph()) !== 'vertex') {
64695 context.map().zoomTo(entity);
64696 context.surface().selectAll(
64697 utilEntityOrMemberSelector([entity.id], context.graph()))
64698 .classed('hover', true);
64703 function checkComment() {
64704 selectAll('.save-section .save-button')
64705 .attr('disabled', (this.value.length ? null : true));
64707 var googleWarning = clippyArea
64710 .data(this.value.match(/google/i) ? [true] : []);
64712 googleWarning.exit()
64715 googleWarning.enter()
64717 .attr('target', '_blank')
64718 .attr('tabindex', -1)
64719 .call(svgIcon('#icon-alert', 'inline'))
64720 .attr('href', t('commit.google_warning_link'))
64722 .text(t('commit.google_warning'));
64726 return utilRebind(commit, dispatch$$1, 'on');
64729 function uiConfirm(selection) {
64730 var modalSelection = uiModal(selection);
64732 modalSelection.select('.modal')
64733 .classed('modal-alert', true);
64735 var section = modalSelection.select('.content');
64737 section.append('div')
64738 .attr('class', 'modal-section header');
64740 section.append('div')
64741 .attr('class', 'modal-section message-text');
64743 var buttons = section.append('div')
64744 .attr('class', 'modal-section buttons cf');
64747 modalSelection.okButton = function() {
64750 .attr('class', 'action col4')
64751 .on('click.confirm', function() {
64752 modalSelection.remove();
64754 .text(t('confirm.okay'));
64756 return modalSelection;
64760 return modalSelection;
64763 function uiConflicts(context) {
64764 var dispatch$$1 = dispatch('download', 'cancel', 'save'),
64768 function conflicts(selection$$1) {
64769 var header = selection$$1
64771 .attr('class', 'header fillL');
64775 .attr('class', 'fr')
64776 .on('click', function() { dispatch$$1.call('cancel'); })
64777 .call(svgIcon('#icon-close'));
64781 .text(t('save.conflict.header'));
64783 var body = selection$$1
64785 .attr('class', 'body fillL');
64789 .attr('class', 'conflicts-help')
64790 .text(t('save.conflict.help'))
64792 .attr('class', 'conflicts-download')
64793 .text(t('save.conflict.download_changes'))
64794 .on('click.download', function() { dispatch$$1.call('download'); });
64798 .attr('class', 'conflict-container fillL3')
64799 .call(showConflict, 0);
64803 .attr('class', 'conflicts-done')
64804 .attr('opacity', 0)
64805 .style('display', 'none')
64806 .text(t('save.conflict.done'));
64810 .attr('class','buttons col12 joined conflicts-buttons');
64814 .attr('disabled', list.length > 1)
64815 .attr('class', 'action conflicts-button col6')
64816 .text(t('save.title'))
64817 .on('click.try_again', function() { dispatch$$1.call('save'); });
64821 .attr('class', 'secondary-action conflicts-button col6')
64822 .text(t('confirm.cancel'))
64823 .on('click.cancel', function() { dispatch$$1.call('cancel'); });
64827 function showConflict(selection$$1, index) {
64828 if (index < 0 || index >= list.length) return;
64830 var parent = select(selection$$1.node().parentNode);
64832 // enable save button if this is the last conflict being reviewed..
64833 if (index === list.length - 1) {
64834 window.setTimeout(function() {
64835 parent.select('.conflicts-button')
64836 .attr('disabled', null);
64838 parent.select('.conflicts-done')
64840 .attr('opacity', 1)
64841 .style('display', 'block');
64845 var item = selection$$1
64846 .selectAll('.conflict')
64847 .data([list[index]]);
64849 var enter = item.enter()
64851 .attr('class', 'conflict');
64855 .attr('class', 'conflict-count')
64856 .text(t('save.conflict.count', { num: index + 1, total: list.length }));
64860 .attr('class', 'conflict-description')
64862 .text(function(d) { return d.name; })
64863 .on('click', function(d) {
64864 zoomToEntity(d.id);
64865 event.preventDefault();
64868 var details = enter
64870 .attr('class', 'conflict-detail-container');
64874 .attr('class', 'conflict-detail-list')
64876 .data(function(d) { return d.details || []; })
64879 .attr('class', 'conflict-detail-item')
64880 .html(function(d) { return d; });
64884 .attr('class', 'conflict-choices')
64889 .attr('class', 'conflict-nav-buttons joined cf')
64890 .selectAll('button')
64891 .data(['previous', 'next'])
64894 .text(function(d) { return t('save.conflict.' + d); })
64895 .attr('class', 'conflict-nav-button action col6')
64896 .attr('disabled', function(d, i) {
64897 return (i === 0 && index === 0) ||
64898 (i === 1 && index === list.length - 1) || null;
64900 .on('click', function(d, i) {
64901 var container = parent.select('.conflict-container'),
64902 sign = (i === 0 ? -1 : 1);
64905 .selectAll('.conflict')
64909 .call(showConflict, index + sign);
64911 event.preventDefault();
64919 function addChoices(selection$$1) {
64920 var choices = selection$$1
64922 .attr('class', 'layer-list')
64924 .data(function(d) { return d.choices || []; });
64926 var enter = choices.enter()
64928 .attr('class', 'layer');
64935 .attr('type', 'radio')
64936 .attr('name', function(d) { return d.id; })
64937 .on('change', function(d, i) {
64938 var ul = this.parentNode.parentNode.parentNode;
64939 ul.__data__.chosen = i;
64945 .text(function(d) { return d.text; });
64948 .each(function(d, i) {
64949 var ul = this.parentNode;
64950 if (ul.__data__.chosen === i) choose(ul, d);
64955 function choose(ul, datum) {
64956 if (event) event.preventDefault();
64960 .classed('active', function(d) { return d === datum; })
64961 .selectAll('input')
64962 .property('checked', function(d) { return d === datum; });
64964 var extent$$1 = geoExtent$$1(),
64967 entity = context.graph().hasEntity(datum.id);
64968 if (entity) extent$$1._extend(entity.extent(context.graph()));
64972 entity = context.graph().hasEntity(datum.id);
64973 if (entity) extent$$1._extend(entity.extent(context.graph()));
64975 zoomToEntity(datum.id, extent$$1);
64979 function zoomToEntity(id, extent$$1) {
64980 context.surface().selectAll('.hover')
64981 .classed('hover', false);
64983 var entity = context.graph().hasEntity(id);
64986 context.map().trimmedExtent(extent$$1);
64988 context.map().zoomTo(entity);
64990 context.surface().selectAll(
64991 utilEntityOrMemberSelector([entity.id], context.graph()))
64992 .classed('hover', true);
64997 // The conflict list should be an array of objects like:
65000 // name: entityName(local),
65001 // details: merge.conflicts(),
65004 // choice(id, keepMine, forceLocal),
65005 // choice(id, keepTheirs, forceRemote)
65008 conflicts.list = function(_) {
65009 if (!arguments.length) return list;
65015 return utilRebind(conflicts, dispatch$$1, 'on');
65018 function uiFlash(selection) {
65019 var modalSelection = uiModal(selection);
65021 modalSelection.select('.modal')
65022 .classed('modal-flash', true);
65024 modalSelection.select('.content')
65025 .classed('modal-section', true)
65027 .attr('class', 'description');
65029 modalSelection.on('click.flash', function() {
65030 modalSelection.remove();
65033 setTimeout(function() {
65034 modalSelection.remove();
65039 return modalSelection;
65042 function uiLasso(context) {
65043 var group, polygon;
65045 lasso.coordinates = [];
65047 function lasso(selection$$1) {
65048 context.container()
65049 .classed('lasso', true);
65051 group = selection$$1
65053 .attr('class', 'lasso hide');
65057 .attr('class', 'lasso-path');
65060 .call(uiToggle(true));
65066 polygon.data([lasso.coordinates])
65067 .attr('d', function(d) { return 'M' + d.join(' L') + ' Z'; });
65072 lasso.extent = function () {
65073 return lasso.coordinates.reduce(function(extent$$1, point) {
65074 return extent$$1.extend(geoExtent$$1(point));
65075 }, geoExtent$$1());
65079 lasso.p = function(_) {
65080 if (!arguments.length) return lasso;
65081 lasso.coordinates.push(_);
65087 lasso.close = function() {
65089 group.call(uiToggle(false, function() {
65090 select(this).remove();
65093 context.container().classed('lasso', false);
65100 function uiRadialMenu(context, operations) {
65106 var radialMenu = function(selection$$1) {
65107 if (!operations.length) return;
65109 selection$$1.node().parentNode.focus();
65111 function click(operation) {
65112 event.stopPropagation();
65113 if (operation.disabled()) return;
65115 radialMenu.close();
65118 menu = selection$$1
65120 .attr('class', 'radial-menu')
65121 .attr('transform', 'translate(' + center + ')')
65122 .attr('opacity', 0);
65126 .attr('opacity', 1);
65131 a1 = a0 + (operations.length - 1) * a;
65135 .attr('class', 'radial-menu-background')
65136 .attr('d', 'M' + r * Math.sin(a0) + ',' +
65138 ' A' + r + ',' + r + ' 0 ' + (operations.length > 5 ? '1' : '0') + ',0 ' +
65139 (r * Math.sin(a1) + 1e-3) + ',' +
65140 (r * Math.cos(a1) + 1e-3)) // Force positive-length path (#1305)
65141 .attr('stroke-width', 50)
65142 .attr('stroke-linecap', 'round');
65144 var button = menu.selectAll()
65148 .attr('class', function(d) { return 'radial-menu-item radial-menu-item-' + d.id; })
65149 .classed('disabled', function(d) { return d.disabled(); })
65150 .attr('transform', function(d, i) {
65151 return 'translate(' + geoRoundCoords([
65152 r * Math.sin(a0 + i * a),
65153 r * Math.cos(a0 + i * a)]).join(',') + ')';
65159 .on('click', click)
65160 .on('mousedown', mousedown)
65161 .on('mouseover', mouseover)
65162 .on('mouseout', mouseout);
65166 .attr('transform', 'translate(-10,-10)')
65167 .attr('width', '20')
65168 .attr('height', '20')
65169 .attr('xlink:href', function(d) { return '#operation-' + d.id; });
65171 tooltip = select(document.body)
65173 .attr('class', 'tooltip-inner radial-menu-tooltip');
65175 function mousedown() {
65176 event.stopPropagation(); // https://github.com/openstreetmap/iD/issues/1869
65179 function mouseover(d, i) {
65180 var rect = context.surfaceRect(),
65181 angle = a0 + i * a,
65182 top = rect.top + (r + 25) * Math.cos(angle) + center[1] + 'px',
65183 left = rect.left + (r + 25) * Math.sin(angle) + center[0] + 'px',
65184 bottom = rect.height - (r + 25) * Math.cos(angle) - center[1] + 'px',
65185 right = rect.width - (r + 25) * Math.sin(angle) - center[0] + 'px';
65188 .style('top', null)
65189 .style('left', null)
65190 .style('bottom', null)
65191 .style('right', null)
65192 .style('display', 'block')
65193 .html(uiTooltipHtml(d.tooltip(), d.keys[0]));
65197 .style('right', right)
65198 .style('top', top);
65199 } else if (i >= 4) {
65201 .style('left', left)
65202 .style('bottom', bottom);
65205 .style('left', left)
65206 .style('top', top);
65210 function mouseout() {
65211 tooltip.style('display', 'none');
65216 radialMenu.close = function() {
65219 .style('pointer-events', 'none')
65221 .attr('opacity', 0)
65231 radialMenu.center = function(_) {
65232 if (!arguments.length) return center;
65241 function uiSelectionList(context, selectedIDs) {
65243 function selectEntity(entity) {
65244 context.enter(modeSelect(context, [entity.id]).suppressMenu(true));
65248 function deselectEntity(entity) {
65249 event.stopPropagation();
65250 var index = selectedIDs.indexOf(entity.id);
65252 selectedIDs.splice(index, 1);
65254 context.enter(modeSelect(context, selectedIDs).suppressMenu(true));
65258 function selectionList(selection$$1) {
65259 selection$$1.classed('selection-list-pane', true);
65261 var header = selection$$1
65263 .attr('class', 'header fillL cf');
65267 .text(t('inspector.multiselect'));
65269 var listWrap = selection$$1
65271 .attr('class', 'inspector-body');
65273 var list = listWrap
65275 .attr('class', 'feature-list cf');
65277 context.history().on('change.selection-list', drawList);
65281 function drawList() {
65282 var entities = selectedIDs
65283 .map(function(id) { return context.hasEntity(id); })
65284 .filter(function(entity) { return entity; });
65286 var items = list.selectAll('.feature-list-item')
65287 .data(entities, osmEntity$$1.key);
65293 var enter = items.enter()
65295 .attr('class', 'feature-list-item')
65296 .on('click', selectEntity);
65300 .attr('class', 'label');
65304 .attr('class', 'close')
65305 .on('click', deselectEntity)
65306 .call(svgIcon('#icon-close'));
65310 .attr('class', 'entity-geom-icon')
65311 .call(svgIcon('', 'pre-text'));
65315 .attr('class', 'entity-type');
65319 .attr('class', 'entity-name');
65322 items = items.merge(enter);
65324 items.selectAll('.entity-geom-icon use')
65325 .attr('href', function() {
65326 var entity = this.parentNode.parentNode.__data__;
65327 return '#icon-' + context.geometry(entity.id);
65330 items.selectAll('.entity-type')
65331 .text(function(entity) { return context.presets().match(entity, context.graph()).name(); });
65333 items.selectAll('.entity-name')
65334 .text(function(entity) { return utilDisplayName(entity); });
65338 return selectionList;
65341 function uiSourceSwitch(context) {
65346 event.preventDefault();
65348 if (context.history().hasChanges() &&
65349 !window.confirm(t('source_switch.lose_changes'))) return;
65351 var live = select(this)
65354 context.connection()
65355 .switch(live ? keys$$1[1] : keys$$1[0]);
65357 context.enter(modeBrowse$$1(context));
65361 .text(live ? t('source_switch.dev') : t('source_switch.live'))
65362 .classed('live', !live);
65365 var sourceSwitch = function(selection$$1) {
65369 .text(t('source_switch.live'))
65370 .classed('live', true)
65371 .attr('tabindex', -1)
65372 .on('click', click);
65376 sourceSwitch.keys = function(_) {
65377 if (!arguments.length) return keys$$1;
65379 return sourceSwitch;
65383 return sourceSwitch;
65386 function uiSuccess(context) {
65387 var dispatch$$1 = dispatch('cancel'),
65391 function success(selection$$1) {
65392 var message = (changeset.comment || t('success.edited_osm')).substring(0, 130) +
65393 ' ' + context.connection().changesetURL(changeset.id);
65395 var header = selection$$1
65397 .attr('class', 'header fillL');
65401 .attr('class', 'fr')
65402 .on('click', function() { dispatch$$1.call('cancel'); })
65403 .call(svgIcon('#icon-close'));
65407 .text(t('success.just_edited'));
65409 var body = selection$$1
65411 .attr('class', 'body save-success fillL');
65415 .html(t('success.help_html'));
65419 .attr('class', 'details')
65420 .attr('target', '_blank')
65421 .attr('tabindex', -1)
65422 .call(svgIcon('#icon-out-link', 'inline'))
65423 .attr('href', t('success.help_link_url'))
65425 .text(t('success.help_link_text'));
65427 var changesetURL = context.connection().changesetURL(changeset.id);
65431 .attr('class', 'button col12 osm')
65432 .attr('target', '_blank')
65433 .attr('href', changesetURL)
65434 .text(t('success.view_on_osm'));
65437 facebook: 'https://facebook.com/sharer/sharer.php?u=' + encodeURIComponent(changesetURL),
65438 twitter: 'https://twitter.com/intent/tweet?source=webclient&text=' + encodeURIComponent(message),
65439 google: 'https://plus.google.com/share?url=' + encodeURIComponent(changesetURL)
65442 body.selectAll('.button.social')
65443 .data(entries(sharing))
65446 .attr('class', 'button social col4')
65447 .attr('target', '_blank')
65448 .attr('href', function(d) { return d.value; })
65450 .title(function(d) { return t('success.' + d.key); })
65451 .placement('bottom'))
65452 .each(function(d) { select(this).call(svgIcon('#logo-' + d.key, 'social')); });
65456 success.changeset = function(_) {
65457 if (!arguments.length) return changeset;
65463 return utilRebind(success, dispatch$$1, 'on');
65466 function coreHistory(context) {
65467 var stack$$1, index, tree$$1,
65468 imageryUsed = ['Bing'],
65469 dispatch$$1 = dispatch('change', 'undone', 'redone'),
65470 lock = utilSessionMutex('lock');
65473 function perform(actions) {
65474 actions = Array.prototype.slice.call(actions);
65478 if (!lodash.isFunction(lodash.last(actions))) {
65479 annotation = actions.pop();
65482 var graph = stack$$1[index].graph;
65483 for (var i = 0; i < actions.length; i++) {
65484 graph = actions[i](graph);
65489 annotation: annotation,
65490 imageryUsed: imageryUsed
65495 function change(previous) {
65496 var difference = coreDifference(previous, history.graph());
65497 dispatch$$1.call('change', this, difference);
65502 // iD uses namespaced keys so multiple installations do not conflict
65503 function getKey(n) {
65504 return 'iD_' + window.location.origin + '_' + n;
65510 graph: function() {
65511 return stack$$1[index].graph;
65516 return stack$$1[0].graph;
65520 merge: function(entities, extent$$1) {
65521 stack$$1[0].graph.rebase(entities, lodash.map(stack$$1, 'graph'), false);
65522 tree$$1.rebase(entities, false);
65524 dispatch$$1.call('change', this, undefined, extent$$1);
65528 perform: function() {
65529 var previous = stack$$1[index].graph;
65531 stack$$1 = stack$$1.slice(0, index + 1);
65532 stack$$1.push(perform(arguments));
65535 return change(previous);
65539 replace: function() {
65540 var previous = stack$$1[index].graph;
65542 // assert(index == stack.length - 1)
65543 stack$$1[index] = perform(arguments);
65545 return change(previous);
65550 var previous = stack$$1[index].graph;
65555 return change(previous);
65560 // Same as calling pop and then perform
65561 overwrite: function() {
65562 var previous = stack$$1[index].graph;
65568 stack$$1 = stack$$1.slice(0, index + 1);
65569 stack$$1.push(perform(arguments));
65572 return change(previous);
65577 var previous = stack$$1[index].graph;
65579 // Pop to the next annotated state.
65580 while (index > 0) {
65582 if (stack$$1[index].annotation) break;
65585 dispatch$$1.call('undone');
65586 return change(previous);
65591 var previous = stack$$1[index].graph;
65593 while (index < stack$$1.length - 1) {
65595 if (stack$$1[index].annotation) break;
65598 dispatch$$1.call('redone');
65599 return change(previous);
65603 undoAnnotation: function() {
65606 if (stack$$1[i].annotation) return stack$$1[i].annotation;
65612 redoAnnotation: function() {
65614 while (i <= stack$$1.length - 1) {
65615 if (stack$$1[i].annotation) return stack$$1[i].annotation;
65621 intersects: function(extent$$1) {
65622 return tree$$1.intersects(extent$$1, stack$$1[index].graph);
65626 difference: function() {
65627 var base = stack$$1[0].graph,
65628 head = stack$$1[index].graph;
65629 return coreDifference(base, head);
65633 changes: function(action) {
65634 var base = stack$$1[0].graph,
65635 head = stack$$1[index].graph;
65638 head = action(head);
65641 var difference = coreDifference(base, head);
65644 modified: difference.modified(),
65645 created: difference.created(),
65646 deleted: difference.deleted()
65651 validate: function(changes) {
65652 return lodash(Validations)
65653 .map(function(fn) { return fn()(changes, stack$$1[index].graph); })
65659 hasChanges: function() {
65660 return this.difference().length() > 0;
65664 imageryUsed: function(sources) {
65666 imageryUsed = sources;
65669 return lodash(stack$$1.slice(1, index + 1))
65670 .map('imageryUsed')
65673 .without(undefined, 'Custom')
65679 reset: function() {
65680 stack$$1 = [{graph: coreGraph$$1()}];
65682 tree$$1 = coreTree(stack$$1[0].graph);
65683 dispatch$$1.call('change');
65688 toJSON: function() {
65689 if (!this.hasChanges()) return;
65691 var allEntities = {},
65693 base = stack$$1[0];
65695 var s = stack$$1.map(function(i) {
65696 var modified = [], deleted = [];
65698 lodash.forEach(i.graph.entities, function(entity, id) {
65700 var key = osmEntity$$1.key(entity);
65701 allEntities[key] = entity;
65702 modified.push(key);
65707 // make sure that the originals of changed or deleted entities get merged
65708 // into the base of the stack after restoring the data from JSON.
65709 if (id in base.graph.entities) {
65710 baseEntities[id] = base.graph.entities[id];
65712 // get originals of parent entities too
65713 lodash.forEach(base.graph._parentWays[id], function(parentId) {
65714 if (parentId in base.graph.entities) {
65715 baseEntities[parentId] = base.graph.entities[parentId];
65722 if (modified.length) x.modified = modified;
65723 if (deleted.length) x.deleted = deleted;
65724 if (i.imageryUsed) x.imageryUsed = i.imageryUsed;
65725 if (i.annotation) x.annotation = i.annotation;
65730 return JSON.stringify({
65732 entities: lodash.values(allEntities),
65733 baseEntities: lodash.values(baseEntities),
65735 nextIDs: osmEntity$$1.id.next,
65741 fromJSON: function(json$$1, loadChildNodes) {
65742 var h = JSON.parse(json$$1),
65743 loadComplete = true;
65745 osmEntity$$1.id.next = h.nextIDs;
65748 if (h.version === 2 || h.version === 3) {
65749 var allEntities = {};
65751 h.entities.forEach(function(entity) {
65752 allEntities[osmEntity$$1.key(entity)] = osmEntity$$1(entity);
65755 if (h.version === 3) {
65756 // This merges originals for changed entities into the base of
65757 // the stack even if the current stack doesn't have them (for
65758 // example when iD has been restarted in a different region)
65759 var baseEntities = h.baseEntities.map(function(d) { return osmEntity$$1(d); });
65760 stack$$1[0].graph.rebase(baseEntities, lodash.map(stack$$1, 'graph'), true);
65761 tree$$1.rebase(baseEntities, true);
65763 // When we restore a modified way, we also need to fetch any missing
65764 // childnodes that would normally have been downloaded with it.. #2142
65765 if (loadChildNodes) {
65766 var missing = lodash(baseEntities)
65767 .filter({ type: 'way' })
65771 .reject(function(n) { return stack$$1[0].graph.hasEntity(n); })
65774 if (!lodash.isEmpty(missing)) {
65775 loadComplete = false;
65776 context.redrawEnable(false);
65778 var loading = uiLoading(context).blocking(true);
65779 context.container().call(loading);
65781 var childNodesLoaded = function(err, result) {
65783 var visible = lodash.groupBy(result.data, 'visible');
65784 if (!lodash.isEmpty(visible.true)) {
65785 missing = lodash.difference(missing, lodash.map(visible.true, 'id'));
65786 stack$$1[0].graph.rebase(visible.true, lodash.map(stack$$1, 'graph'), true);
65787 tree$$1.rebase(visible.true, true);
65790 // fetch older versions of nodes that were deleted..
65791 lodash.each(visible.false, function(entity) {
65792 context.connection()
65793 .loadEntityVersion(entity.id, +entity.version - 1, childNodesLoaded);
65797 if (err || lodash.isEmpty(missing)) {
65799 context.redrawEnable(true);
65800 dispatch$$1.call('change');
65804 context.connection().loadMultiple(missing, childNodesLoaded);
65809 stack$$1 = h.stack.map(function(d) {
65810 var entities = {}, entity;
65813 d.modified.forEach(function(key) {
65814 entity = allEntities[key];
65815 entities[entity.id] = entity;
65820 d.deleted.forEach(function(id) {
65821 entities[id] = undefined;
65826 graph: coreGraph$$1(stack$$1[0].graph).load(entities),
65827 annotation: d.annotation,
65828 imageryUsed: d.imageryUsed
65832 } else { // original version
65833 stack$$1 = h.stack.map(function(d) {
65836 for (var i in d.entities) {
65837 var entity = d.entities[i];
65838 entities[i] = entity === 'undefined' ? undefined : osmEntity$$1(entity);
65841 d.graph = coreGraph$$1(stack$$1[0].graph).load(entities);
65846 if (loadComplete) {
65847 dispatch$$1.call('change');
65855 if (lock.locked()) context.storage(getKey('saved_history'), history.toJSON() || null);
65860 clearSaved: function() {
65861 context.debouncedSave.cancel();
65862 if (lock.locked()) context.storage(getKey('saved_history'), null);
65868 return lock.lock();
65872 unlock: function() {
65877 // is iD not open in another window and it detects that
65878 // there's a history stored in localStorage that's recoverable?
65879 restorableChanges: function() {
65880 return lock.locked() && !!context.storage(getKey('saved_history'));
65884 // load history from a version stored in localStorage
65885 restore: function() {
65886 if (!lock.locked()) return;
65888 var json$$1 = context.storage(getKey('saved_history'));
65889 if (json$$1) history.fromJSON(json$$1, true);
65900 return utilRebind(history, dispatch$$1, 'on');
65903 function presetCollection(collection) {
65904 var maxSearchResults = 50,
65905 maxSuggestionResults = 10;
65909 collection: collection,
65912 item: function(id) {
65913 return lodash.find(collection, function(d) {
65914 return d.id === id;
65919 matchGeometry: function(geometry) {
65920 return presetCollection(collection.filter(function(d) {
65921 return d.matchGeometry(geometry);
65926 search: function(value, geometry) {
65927 if (!value) return this;
65929 function leading(a) {
65930 var index = a.indexOf(value);
65931 return index === 0 || a[index - 1] === ' ';
65934 function suggestionName(name) {
65935 var nameArray = name.split(' - ');
65936 if (nameArray.length > 1) {
65937 name = nameArray.slice(0, nameArray.length - 1).join(' - ');
65939 return name.toLowerCase();
65943 value = value.toLowerCase();
65945 var searchable = lodash.filter(collection, function(a) {
65946 return a.searchable !== false && a.suggestion !== true;
65948 suggestions = lodash.filter(collection, function(a) {
65949 return a.suggestion === true;
65953 // matches value to preset.name
65954 var leading_name = lodash.filter(searchable, function(a) {
65955 return leading(a.name().toLowerCase());
65956 }).sort(function(a, b) {
65957 var i = a.name().toLowerCase().indexOf(value) - b.name().toLowerCase().indexOf(value);
65958 if (i === 0) return a.name().length - b.name().length;
65962 // matches value to preset.terms values
65963 var leading_terms = lodash.filter(searchable, function(a) {
65964 return lodash.some(a.terms() || [], leading);
65967 // matches value to preset.tags values
65968 var leading_tag_values = lodash.filter(searchable, function(a) {
65969 return lodash.some(lodash.without(lodash.values(a.tags || {}), '*'), leading);
65973 // finds close matches to value in preset.name
65974 var similar_name = searchable.map(function(a) {
65977 dist: utilEditDistance(value, a.name())
65979 }).filter(function(a) {
65980 return a.dist + Math.min(value.length - a.preset.name().length, 0) < 3;
65981 }).sort(function(a, b) {
65982 return a.dist - b.dist;
65983 }).map(function(a) {
65987 // finds close matches to value in preset.terms
65988 var similar_terms = lodash.filter(searchable, function(a) {
65989 return lodash.some(a.terms() || [], function(b) {
65990 return utilEditDistance(value, b) + Math.min(value.length - b.length, 0) < 3;
65994 var leading_suggestions = lodash.filter(suggestions, function(a) {
65995 return leading(suggestionName(a.name()));
65996 }).sort(function(a, b) {
65997 a = suggestionName(a.name());
65998 b = suggestionName(b.name());
65999 var i = a.indexOf(value) - b.indexOf(value);
66000 if (i === 0) return a.length - b.length;
66004 var similar_suggestions = suggestions.map(function(a) {
66007 dist: utilEditDistance(value, suggestionName(a.name()))
66009 }).filter(function(a) {
66010 return a.dist + Math.min(value.length - suggestionName(a.preset.name()).length, 0) < 1;
66011 }).sort(function(a, b) {
66012 return a.dist - b.dist;
66013 }).map(function(a) {
66017 var other = presets.item(geometry);
66019 var results = leading_name.concat(
66021 leading_tag_values,
66022 leading_suggestions.slice(0, maxSuggestionResults + 5),
66025 similar_suggestions.slice(0, maxSuggestionResults)
66026 ).slice(0, maxSearchResults - 1);
66028 return presetCollection(lodash.uniq(results.concat(other)));
66036 function presetCategory(id, category, all) {
66037 category = lodash.clone(category);
66042 category.members = presetCollection(category.members.map(function(id) {
66043 return all.item(id);
66047 category.matchGeometry = function(geometry) {
66048 return category.geometry.indexOf(geometry) >= 0;
66052 category.matchScore = function() {
66057 category.name = function() {
66058 return t('presets.categories.' + id + '.name', {'default': id});
66062 category.terms = function() {
66070 function presetField(id, field) {
66071 field = lodash.clone(field);
66076 field.matchGeometry = function(geometry) {
66077 return !field.geometry || field.geometry === geometry;
66081 field.t = function(scope, options) {
66082 return t('presets.fields.' + id + '.' + scope, options);
66086 field.label = function() {
66087 return field.t('label', {'default': id});
66091 var placeholder = field.placeholder;
66092 field.placeholder = function() {
66093 return field.t('placeholder', {'default': placeholder});
66100 function presetPreset(id, preset, fields) {
66101 preset = lodash.clone(preset);
66104 preset.fields = (preset.fields || []).map(getFields);
66105 preset.geometry = (preset.geometry || []);
66108 function getFields(f) {
66113 preset.matchGeometry = function(geometry) {
66114 return preset.geometry.indexOf(geometry) >= 0;
66118 var matchScore = preset.matchScore || 1;
66119 preset.matchScore = function(entity) {
66120 var tags = preset.tags,
66123 for (var t$$1 in tags) {
66124 if (entity.tags[t$$1] === tags[t$$1]) {
66125 score += matchScore;
66126 } else if (tags[t$$1] === '*' && t$$1 in entity.tags) {
66127 score += matchScore / 2;
66137 preset.t = function(scope, options) {
66138 return t('presets.presets.' + id + '.' + scope, options);
66142 var name = preset.name || '';
66143 preset.name = function() {
66144 if (preset.suggestion) {
66145 id = id.split('/');
66146 id = id[0] + '/' + id[1];
66147 return name + ' - ' + t('presets.presets.' + id + '.name');
66149 return preset.t('name', {'default': name});
66153 preset.terms = function() {
66154 return preset.t('terms', {'default': ''}).toLowerCase().trim().split(/\s*,+\s*/);
66158 preset.isFallback = function() {
66159 var tagCount = Object.keys(preset.tags).length;
66160 return tagCount === 0 || (tagCount === 1 && preset.tags.hasOwnProperty('area'));
66164 preset.reference = function(geometry) {
66165 var key = Object.keys(preset.tags)[0],
66166 value = preset.tags[key];
66168 if (geometry === 'relation' && key === 'type') {
66169 if (value in preset.tags) {
66171 value = preset.tags[key];
66173 return { rtype: value };
66177 if (value === '*') {
66178 return { key: key };
66180 return { key: key, value: value };
66185 var removeTags = preset.removeTags || preset.tags;
66186 preset.removeTags = function(tags, geometry) {
66187 tags = lodash.omit(tags, lodash.keys(removeTags));
66189 for (var f in preset.fields) {
66190 var field = preset.fields[f];
66191 if (field.matchGeometry(geometry) && field.default === tags[field.key]) {
66192 delete tags[field.key];
66201 var applyTags = preset.addTags || preset.tags;
66202 preset.applyTags = function(tags, geometry) {
66205 tags = lodash.clone(tags);
66207 for (k in applyTags) {
66208 if (applyTags[k] === '*') {
66211 tags[k] = applyTags[k];
66215 // Add area=yes if necessary.
66216 // This is necessary if the geometry is already an area (e.g. user drew an area) AND any of:
66217 // 1. chosen preset could be either an area or a line (`barrier=city_wall`)
66218 // 2. chosen preset doesn't have a key in areaKeys (`railway=station`)
66219 if (geometry === 'area') {
66220 var needsAreaTag = true;
66221 if (preset.geometry.indexOf('line') === -1) {
66222 for (k in applyTags) {
66223 if (k in areaKeys) {
66224 needsAreaTag = false;
66229 if (needsAreaTag) {
66234 for (var f in preset.fields) {
66235 var field = preset.fields[f];
66236 if (field.matchGeometry(geometry) && field.key && !tags[field.key] && field.default) {
66237 tags[field.key] = field.default;
66248 function presetIndex() {
66249 // a presetCollection with methods for
66250 // loading new data and returning defaults
66252 var all = presetCollection([]),
66253 defaults = { area: all, line: all, point: all, vertex: all, relation: all },
66256 recent = presetCollection([]);
66258 // Index of presets by (geometry, tag key).
66267 all.match = function(entity, resolver) {
66268 var geometry = entity.geometry(resolver);
66270 // Treat entities on addr:interpolation lines as points, not vertices (#3241)
66271 if (geometry === 'vertex' && entity.isOnAddressLine(resolver)) {
66272 geometry = 'point';
66275 var geometryMatches = index[geometry],
66279 for (var k in entity.tags) {
66280 var keyMatches = geometryMatches[k];
66281 if (!keyMatches) continue;
66283 for (var i = 0; i < keyMatches.length; i++) {
66284 var score = keyMatches[i].matchScore(entity);
66285 if (score > best) {
66287 match = keyMatches[i];
66292 return match || all.item(geometry);
66296 // Because of the open nature of tagging, iD will never have a complete
66297 // list of tags used in OSM, so we want it to have logic like "assume
66298 // that a closed way with an amenity tag is an area, unless the amenity
66299 // is one of these specific types". This function computes a structure
66300 // that allows testing of such conditions, based on the presets designated
66301 // as as supporting (or not supporting) the area geometry.
66303 // The returned object L is a whitelist/blacklist of tags. A closed way
66304 // with a tag (k, v) is considered to be an area if `k in L && !(v in L[k])`
66305 // (see `Way#isArea()`). In other words, the keys of L form the whitelist,
66306 // and the subkeys form the blacklist.
66307 all.areaKeys = function() {
66309 ignore = ['barrier', 'highway', 'footway', 'railway', 'type'],
66310 presets = lodash.reject(all.collection, 'suggestion');
66313 presets.forEach(function(d) {
66314 for (var key in d.tags) break;
66316 if (ignore.indexOf(key) !== -1) return;
66318 if (d.geometry.indexOf('area') !== -1) {
66319 areaKeys[key] = areaKeys[key] || {};
66324 presets.forEach(function(d) {
66325 for (var key in d.tags) break;
66327 if (ignore.indexOf(key) !== -1) return;
66329 var value = d.tags[key];
66330 if (d.geometry.indexOf('area') === -1 &&
66331 d.geometry.indexOf('line') !== -1 &&
66332 key in areaKeys && value !== '*') {
66333 areaKeys[key][value] = true;
66341 all.init = function() {
66342 var d = data.presets;
66345 lodash.forEach(d.fields, function(d, id) {
66346 fields[id] = presetField(id, d);
66347 if (d.universal) universal.push(fields[id]);
66352 lodash.forEach(d.presets, function(d, id) {
66353 all.collection.push(presetPreset(id, d, fields));
66357 if (d.categories) {
66358 lodash.forEach(d.categories, function(d, id) {
66359 all.collection.push(presetCategory(id, d, all));
66364 var getItem = lodash.bind(all.item, all);
66366 area: presetCollection(d.defaults.area.map(getItem)),
66367 line: presetCollection(d.defaults.line.map(getItem)),
66368 point: presetCollection(d.defaults.point.map(getItem)),
66369 vertex: presetCollection(d.defaults.vertex.map(getItem)),
66370 relation: presetCollection(d.defaults.relation.map(getItem))
66374 for (var i = 0; i < all.collection.length; i++) {
66375 var preset = all.collection[i],
66376 geometry = preset.geometry;
66378 for (var j = 0; j < geometry.length; j++) {
66379 var g = index[geometry[j]];
66380 for (var k in preset.tags) {
66381 (g[k] = g[k] || []).push(preset);
66389 all.field = function(id) {
66393 all.universal = function() {
66397 all.defaults = function(geometry, n) {
66398 var rec = recent.matchGeometry(geometry).collection.slice(0, 4),
66399 def = lodash.uniq(rec.concat(defaults[geometry].collection)).slice(0, n - 1);
66400 return presetCollection(lodash.uniq(rec.concat(def).concat(all.item(geometry))));
66403 all.choose = function(preset) {
66404 if (!preset.isFallback()) {
66405 recent = presetCollection(lodash.uniq([preset].concat(recent.collection)));
66415 function setAreaKeys(value) {
66420 function coreContext() {
66421 addTranslation('en', en);
66424 var dispatch$$1 = dispatch('enter', 'exit', 'change'),
66427 // https://github.com/openstreetmap/iD/issues/772
66428 // http://mathiasbynens.be/notes/localstorage-pattern#comment-9
66430 try { storage = localStorage; } catch (e) {} // eslint-disable-line no-empty
66431 storage = storage || (function() {
66434 getItem: function(k) { return s[k]; },
66435 setItem: function(k, v) { s[k] = v; },
66436 removeItem: function(k) { delete s[k]; }
66440 context.storage = function(k, v) {
66442 if (arguments.length === 1) return storage.getItem(k);
66443 else if (v === null) storage.removeItem(k);
66444 else storage.setItem(k, v);
66446 // localstorage quota exceeded
66447 /* eslint-disable no-console */
66448 if (typeof console !== 'undefined') console.error('localStorage quota exceeded');
66449 /* eslint-enable no-console */
66454 /* Straight accessors. Avoid using these if you can. */
66455 var ui, connection, history;
66456 context.ui = function() { return ui; };
66457 context.connection = function() { return connection; };
66458 context.history = function() { return history; };
66462 function entitiesLoaded(err, result) {
66463 if (!err) history.merge(result.data, result.extent);
66466 context.preauth = function(options) {
66467 connection.switch(options);
66471 context.loadTiles = function(projection, dimensions, callback) {
66472 function done(err, result) {
66473 entitiesLoaded(err, result);
66474 if (callback) callback(err, result);
66476 connection.loadTiles(projection, dimensions, done);
66479 context.loadEntity = function(id, callback) {
66480 function done(err, result) {
66481 entitiesLoaded(err, result);
66482 if (callback) callback(err, result);
66484 connection.loadEntity(id, done);
66487 context.zoomToEntity = function(id, zoomTo) {
66488 if (zoomTo !== false) {
66489 this.loadEntity(id, function(err, result) {
66491 var entity = lodash.find(result.data, function(e) { return e.id === id; });
66492 if (entity) { map$$1.zoomTo(entity); }
66496 map$$1.on('drawn.zoomToEntity', function() {
66497 if (!context.hasEntity(id)) return;
66498 map$$1.on('drawn.zoomToEntity', null);
66499 context.on('enter.zoomToEntity', null);
66500 context.enter(modeSelect(context, [id]));
66503 context.on('enter.zoomToEntity', function() {
66504 if (mode.id !== 'browse') {
66505 map$$1.on('drawn.zoomToEntity', null);
66506 context.on('enter.zoomToEntity', null);
66511 var minEditableZoom = 16;
66512 context.minEditableZoom = function(_) {
66513 if (!arguments.length) return minEditableZoom;
66514 minEditableZoom = _;
66515 connection.tileZoom(_);
66521 var inIntro = false;
66522 context.inIntro = function(_) {
66523 if (!arguments.length) return inIntro;
66528 context.save = function() {
66529 if (inIntro || (mode && mode.id === 'save') || select('.modal').size()) return;
66531 if (history.hasChanges()) return t('save.unsaved_changes');
66536 context.hasEntity = function(id) {
66537 return history.graph().hasEntity(id);
66539 context.entity = function(id) {
66540 return history.graph().entity(id);
66542 context.childNodes = function(way) {
66543 return history.graph().childNodes(way);
66545 context.geometry = function(id) {
66546 return context.entity(id).geometry(history.graph());
66552 context.mode = function() {
66555 context.enter = function(newMode) {
66558 dispatch$$1.call('exit', this, mode);
66563 dispatch$$1.call('enter', this, mode);
66566 context.selectedIDs = function() {
66567 if (mode && mode.selectedIDs) {
66568 return mode.selectedIDs();
66576 context.install = function(behavior) {
66577 context.surface().call(behavior);
66579 context.uninstall = function(behavior) {
66580 context.surface().call(behavior.off);
66585 var copyIDs = [], copyGraph;
66586 context.copyGraph = function() { return copyGraph; };
66587 context.copyIDs = function(_) {
66588 if (!arguments.length) return copyIDs;
66590 copyGraph = history.graph();
66597 context.background = function() { return background; };
66602 context.features = function() { return features; };
66603 context.hasHiddenConnections = function(id) {
66604 var graph = history.graph(),
66605 entity = graph.entity(id);
66606 return features.hasHiddenConnections(entity, graph);
66612 context.presets = function() { return presets; };
66617 context.map = function() { return map$$1; };
66618 context.layers = function() { return map$$1.layers; };
66619 context.surface = function() { return map$$1.surface; };
66620 context.editable = function() { return map$$1.editable(); };
66622 context.surfaceRect = function() {
66623 // Work around a bug in Firefox.
66624 // http://stackoverflow.com/questions/18153989/
66625 // https://bugzilla.mozilla.org/show_bug.cgi?id=530985
66626 return context.surface().node().parentNode.getBoundingClientRect();
66638 context.debugFlags = function() {
66641 context.setDebug = function(flag, val) {
66642 if (arguments.length === 1) val = true;
66643 debugFlags[flag] = val;
66644 dispatch$$1.call('change');
66647 context.getDebug = function(flag) {
66648 return flag && debugFlags[flag];
66653 var container, embed;
66654 context.container = function(_) {
66655 if (!arguments.length) return container;
66657 container.classed('id-container', true);
66660 context.embed = function(_) {
66661 if (!arguments.length) return embed;
66668 var assetPath = '';
66669 context.assetPath = function(_) {
66670 if (!arguments.length) return assetPath;
66676 context.assetMap = function(_) {
66677 if (!arguments.length) return assetMap;
66682 context.asset = function(_) {
66683 var filename = assetPath + _;
66684 return assetMap[filename] || filename;
66687 context.imagePath = function(_) {
66688 return context.asset('img/' + _);
66693 // `locale` variable contains a "requested locale".
66694 // It won't become the `currentLocale` until after loadLocale() is called.
66695 var locale, localePath;
66697 context.locale = function(loc, path$$1) {
66698 if (!arguments.length) return currentLocale;
66700 localePath = path$$1;
66704 context.loadLocale = function(callback) {
66705 if (locale && locale !== 'en' && dataLocales.indexOf(locale) !== -1) {
66706 localePath = localePath || context.asset('locales/' + locale + '.json');
66707 json(localePath, function(err, result) {
66709 addTranslation(locale, result[locale]);
66729 /* reset (aka flush) */
66730 context.reset = context.flush = function() {
66731 context.debouncedSave.cancel();
66732 lodash.each(services, function(service) {
66733 if (service && typeof service.reset === 'function') {
66734 service.reset(context);
66744 context.version = '2.0.1';
66746 context.projection = geoRawMercator();
66748 locale = utilDetect().locale;
66749 if (locale && dataLocales.indexOf(locale) === -1) {
66750 locale = locale.split('-')[0];
66753 history = coreHistory(context);
66754 context.graph = history.graph;
66755 context.changes = history.changes;
66756 context.intersects = history.intersects;
66758 // Debounce save, since it's a synchronous localStorage write,
66759 // and history changes can happen frequently (e.g. when dragging).
66760 context.debouncedSave = lodash.debounce(context.save, 350);
66761 function withDebouncedSave(fn) {
66762 return function() {
66763 var result = fn.apply(history, arguments);
66764 context.debouncedSave();
66769 context.perform = withDebouncedSave(history.perform);
66770 context.replace = withDebouncedSave(history.replace);
66771 context.pop = withDebouncedSave(history.pop);
66772 context.overwrite = withDebouncedSave(history.overwrite);
66773 context.undo = withDebouncedSave(history.undo);
66774 context.redo = withDebouncedSave(history.redo);
66776 ui = uiInit(context);
66778 connection = services.osm;
66780 background = rendererBackground(context);
66781 features = rendererFeatures(context);
66782 presets = presetIndex();
66784 map$$1 = rendererMap(context);
66785 context.mouse = map$$1.mouse;
66786 context.extent = map$$1.extent;
66787 context.pan = map$$1.pan;
66788 context.zoomIn = map$$1.zoomIn;
66789 context.zoomOut = map$$1.zoomOut;
66790 context.zoomInFurther = map$$1.zoomInFurther;
66791 context.zoomOutFurther = map$$1.zoomOutFurther;
66792 context.redrawEnable = map$$1.redrawEnable;
66796 areaKeys = presets.areaKeys();
66798 lodash.each(services, function(service) {
66799 if (service && typeof service.init === 'function') {
66800 service.init(context);
66805 return utilRebind(context, dispatch$$1, 'on');
66808 function osmWay() {
66809 if (!(this instanceof osmWay)) {
66810 return (new osmWay()).initialize(arguments);
66811 } else if (arguments.length) {
66812 this.initialize(arguments);
66817 osmEntity$$1.way = osmWay;
66819 osmWay.prototype = Object.create(osmEntity$$1.prototype);
66822 lodash.extend(osmWay.prototype, {
66827 copy: function(resolver, copies) {
66828 if (copies[this.id])
66829 return copies[this.id];
66831 var copy = osmEntity$$1.prototype.copy.call(this, resolver, copies);
66833 var nodes = this.nodes.map(function(id) {
66834 return resolver.entity(id).copy(resolver, copies).id;
66837 copy = copy.update({ nodes: nodes });
66838 copies[this.id] = copy;
66844 extent: function(resolver) {
66845 return resolver.transient(this, 'extent', function() {
66846 var extent$$1 = geoExtent$$1();
66847 for (var i = 0; i < this.nodes.length; i++) {
66848 var node = resolver.hasEntity(this.nodes[i]);
66850 extent$$1._extend(node.extent());
66858 first: function() {
66859 return this.nodes[0];
66864 return this.nodes[this.nodes.length - 1];
66868 contains: function(node) {
66869 return this.nodes.indexOf(node) >= 0;
66873 affix: function(node) {
66874 if (this.nodes[0] === node) return 'prefix';
66875 if (this.nodes[this.nodes.length - 1] === node) return 'suffix';
66879 layer: function() {
66880 // explicit layer tag, clamp between -10, 10..
66881 if (isFinite(this.tags.layer)) {
66882 return Math.max(-10, Math.min(+(this.tags.layer), 10));
66885 // implied layer tag..
66886 if (this.tags.location === 'overground') return 1;
66887 if (this.tags.location === 'underground') return -1;
66888 if (this.tags.location === 'underwater') return -10;
66890 if (this.tags.power === 'line') return 10;
66891 if (this.tags.power === 'minor_line') return 10;
66892 if (this.tags.aerialway) return 10;
66893 if (this.tags.bridge) return 1;
66894 if (this.tags.cutting) return -1;
66895 if (this.tags.tunnel) return -1;
66896 if (this.tags.waterway) return -1;
66897 if (this.tags.man_made === 'pipeline') return -10;
66898 if (this.tags.boundary) return -10;
66903 isOneWay: function() {
66904 // explicit oneway tag..
66905 if (['yes', '1', '-1'].indexOf(this.tags.oneway) !== -1) { return true; }
66906 if (['no', '0'].indexOf(this.tags.oneway) !== -1) { return false; }
66908 // implied oneway tag..
66909 for (var key in this.tags) {
66910 if (key in osmOneWayTags && (this.tags[key] in osmOneWayTags[key]))
66917 lanes: function() {
66918 return osmLanes(this);
66922 isClosed: function() {
66923 return this.nodes.length > 0 && this.first() === this.last();
66927 isConvex: function(resolver) {
66928 if (!this.isClosed() || this.isDegenerate()) return null;
66930 var nodes = lodash.uniq(resolver.childNodes(this)),
66931 coords = lodash.map(nodes, 'loc'),
66932 curr = 0, prev = 0;
66934 for (var i = 0; i < coords.length; i++) {
66935 var o = coords[(i+1) % coords.length],
66937 b = coords[(i+2) % coords.length],
66938 res = geoCross(o, a, b);
66940 curr = (res > 0) ? 1 : (res < 0) ? -1 : 0;
66943 } else if (prev && curr !== prev) {
66952 isArea: function() {
66953 if (this.tags.area === 'yes')
66955 if (!this.isClosed() || this.tags.area === 'no')
66957 for (var key in this.tags) {
66958 if (key in areaKeys && !(this.tags[key] in areaKeys[key])) {
66966 isDegenerate: function() {
66967 return lodash.uniq(this.nodes).length < (this.isArea() ? 3 : 2);
66971 areAdjacent: function(n1, n2) {
66972 for (var i = 0; i < this.nodes.length; i++) {
66973 if (this.nodes[i] === n1) {
66974 if (this.nodes[i - 1] === n2) return true;
66975 if (this.nodes[i + 1] === n2) return true;
66982 geometry: function(graph) {
66983 return graph.transient(this, 'geometry', function() {
66984 return this.isArea() ? 'area' : 'line';
66989 addNode: function(id, index) {
66990 var nodes = this.nodes.slice();
66991 nodes.splice(index === undefined ? nodes.length : index, 0, id);
66992 return this.update({nodes: nodes});
66996 updateNode: function(id, index) {
66997 var nodes = this.nodes.slice();
66998 nodes.splice(index, 1, id);
66999 return this.update({nodes: nodes});
67003 replaceNode: function(needle, replacement) {
67004 if (this.nodes.indexOf(needle) < 0)
67007 var nodes = this.nodes.slice();
67008 for (var i = 0; i < nodes.length; i++) {
67009 if (nodes[i] === needle) {
67010 nodes[i] = replacement;
67013 return this.update({nodes: nodes});
67017 removeNode: function(id) {
67020 for (var i = 0; i < this.nodes.length; i++) {
67021 var node = this.nodes[i];
67022 if (node !== id && nodes[nodes.length - 1] !== node) {
67027 // Preserve circularity
67028 if (this.nodes.length > 1 && this.first() === id && this.last() === id && nodes[nodes.length - 1] !== nodes[0]) {
67029 nodes.push(nodes[0]);
67032 return this.update({nodes: nodes});
67036 asJXON: function(changeset_id) {
67039 '@id': this.osmId(),
67040 '@version': this.version || 0,
67041 nd: lodash.map(this.nodes, function(id) {
67042 return { keyAttributes: { ref: osmEntity$$1.id.toOSM(id) } };
67044 tag: lodash.map(this.tags, function(v, k) {
67045 return { keyAttributes: { k: k, v: v } };
67049 if (changeset_id) r.way['@changeset'] = changeset_id;
67054 asGeoJSON: function(resolver) {
67055 return resolver.transient(this, 'GeoJSON', function() {
67056 var coordinates = lodash.map(resolver.childNodes(this), 'loc');
67057 if (this.isArea() && this.isClosed()) {
67060 coordinates: [coordinates]
67064 type: 'LineString',
67065 coordinates: coordinates
67072 area: function(resolver) {
67073 return resolver.transient(this, 'area', function() {
67074 var nodes = resolver.childNodes(this);
67078 coordinates: [lodash.map(nodes, 'loc')]
67081 if (!this.isClosed() && nodes.length) {
67082 json$$1.coordinates[0].push(nodes[0].loc);
67085 var area$$1 = area$1(json$$1);
67087 // Heuristic for detecting counterclockwise winding order. Assumes
67088 // that OpenStreetMap polygons are not hemisphere-spanning.
67089 if (area$$1 > 2 * Math.PI) {
67090 json$$1.coordinates[0] = json$$1.coordinates[0].reverse();
67091 area$$1 = area$1(json$$1);
67094 return isNaN(area$$1) ? 0 : area$$1;
67099 function osmTurn(turn) {
67100 if (!(this instanceof osmTurn))
67101 return new osmTurn(turn);
67102 lodash.extend(this, turn);
67106 function osmIntersection(graph, vertexId) {
67107 var vertex = graph.entity(vertexId),
67108 parentWays = graph.parentWays(vertex),
67112 function addHighway(way, adjacentNodeId) {
67113 if (highways[adjacentNodeId]) {
67114 coincident.push(adjacentNodeId);
67116 highways[adjacentNodeId] = way;
67120 // Pre-split ways that would need to be split in
67121 // order to add a restriction. The real split will
67122 // happen when the restriction is added.
67123 parentWays.forEach(function(way) {
67124 if (!way.tags.highway || way.isArea() || way.isDegenerate())
67127 var isFirst = (vertexId === way.first()),
67128 isLast = (vertexId === way.last()),
67129 isAffix = (isFirst || isLast),
67130 isClosingNode = (isFirst && isLast);
67132 if (isAffix && !isClosingNode) {
67133 var index = (isFirst ? 1 : way.nodes.length - 2);
67134 addHighway(way, way.nodes[index]);
67137 var splitIndex, wayA, wayB, indexA, indexB;
67138 if (isClosingNode) {
67139 splitIndex = Math.ceil(way.nodes.length / 2); // split at midpoint
67140 wayA = osmWay({id: way.id + '-a', tags: way.tags, nodes: way.nodes.slice(0, splitIndex)});
67141 wayB = osmWay({id: way.id + '-b', tags: way.tags, nodes: way.nodes.slice(splitIndex)});
67143 indexB = way.nodes.length - 2;
67145 splitIndex = lodash.indexOf(way.nodes, vertex.id, 1); // split at vertexid
67146 wayA = osmWay({id: way.id + '-a', tags: way.tags, nodes: way.nodes.slice(0, splitIndex + 1)});
67147 wayB = osmWay({id: way.id + '-b', tags: way.tags, nodes: way.nodes.slice(splitIndex)});
67148 indexA = splitIndex - 1;
67149 indexB = splitIndex + 1;
67151 graph = graph.replace(wayA).replace(wayB);
67152 addHighway(wayA, way.nodes[indexA]);
67153 addHighway(wayB, way.nodes[indexB]);
67157 // remove any ways from this intersection that are coincident
67158 // (i.e. any adjacent node used by more than one intersecting way)
67159 coincident.forEach(function (n) {
67160 delete highways[n];
67164 var intersection = {
67165 highways: highways,
67166 ways: lodash.values(highways),
67171 intersection.adjacentNodeId = function(fromWayId) {
67172 return lodash.find(lodash.keys(highways), function(k) {
67173 return highways[k].id === fromWayId;
67178 intersection.turns = function(fromNodeId) {
67179 var start = highways[fromNodeId];
67183 if (start.first() === vertex.id && start.tags.oneway === 'yes')
67185 if (start.last() === vertex.id && start.tags.oneway === '-1')
67188 function withRestriction(turn) {
67189 graph.parentRelations(graph.entity(turn.from.way)).forEach(function(relation) {
67190 if (relation.tags.type !== 'restriction')
67193 var f = relation.memberByRole('from'),
67194 t = relation.memberByRole('to'),
67195 v = relation.memberByRole('via');
67197 if (f && f.id === turn.from.way &&
67198 v && v.id === turn.via.node &&
67199 t && t.id === turn.to.way) {
67200 turn.restriction = relation.id;
67201 } else if (/^only_/.test(relation.tags.restriction) &&
67202 f && f.id === turn.from.way &&
67203 v && v.id === turn.via.node &&
67204 t && t.id !== turn.to.way) {
67205 turn.restriction = relation.id;
67206 turn.indirect_restriction = true;
67210 return osmTurn(turn);
67216 way: start.id.split(/-(a|b)/)[0]
67218 via = { node: vertex.id },
67221 lodash.each(highways, function(end, adjacentNodeId) {
67226 if (end.first() !== vertex.id && end.tags.oneway !== 'yes') {
67227 turns.push(withRestriction({
67231 node: adjacentNodeId,
67232 way: end.id.split(/-(a|b)/)[0]
67238 if (end.last() !== vertex.id && end.tags.oneway !== '-1') {
67239 turns.push(withRestriction({
67243 node: adjacentNodeId,
67244 way: end.id.split(/-(a|b)/)[0]
67252 if (start.tags.oneway !== 'yes' && start.tags.oneway !== '-1') {
67253 turns.push(withRestriction({
67264 return intersection;
67268 function osmInferRestriction(graph, from, via, to, projection) {
67269 var fromWay = graph.entity(from.way),
67270 fromNode = graph.entity(from.node),
67271 toWay = graph.entity(to.way),
67272 toNode = graph.entity(to.node),
67273 viaNode = graph.entity(via.node),
67274 fromOneWay = (fromWay.tags.oneway === 'yes' && fromWay.last() === via.node) ||
67275 (fromWay.tags.oneway === '-1' && fromWay.first() === via.node),
67276 toOneWay = (toWay.tags.oneway === 'yes' && toWay.first() === via.node) ||
67277 (toWay.tags.oneway === '-1' && toWay.last() === via.node),
67278 angle = geoAngle(viaNode, fromNode, projection) -
67279 geoAngle(viaNode, toNode, projection);
67281 angle = angle * 180 / Math.PI;
67286 if (fromNode === toNode)
67287 return 'no_u_turn';
67288 if ((angle < 23 || angle > 336) && fromOneWay && toOneWay)
67289 return 'no_u_turn';
67291 return 'no_right_turn';
67293 return 'no_left_turn';
67295 return 'no_straight_on';
67298 function actionAddMember(relationId, member, memberIndex) {
67299 return function(graph) {
67300 var relation = graph.entity(relationId);
67302 if (isNaN(memberIndex) && member.type === 'way') {
67303 var members = relation.indexedMembers();
67304 members.push(member);
67306 var joined = osmJoinWays(members, graph);
67307 for (var i = 0; i < joined.length; i++) {
67308 var segment = joined[i];
67309 for (var j = 0; j < segment.length && segment.length >= 2; j++) {
67310 if (segment[j] !== member)
67314 memberIndex = segment[j + 1].index;
67315 } else if (j === segment.length - 1) {
67316 memberIndex = segment[j - 1].index + 1;
67318 memberIndex = Math.min(segment[j - 1].index + 1, segment[j + 1].index + 1);
67324 return graph.replace(relation.addMember(member, memberIndex));
67328 function actionAddMidpoint(midpoint, node) {
67329 return function(graph) {
67330 graph = graph.replace(node.move(midpoint.loc));
67332 var parents = lodash.intersection(
67333 graph.parentWays(graph.entity(midpoint.edge[0])),
67334 graph.parentWays(graph.entity(midpoint.edge[1])));
67336 parents.forEach(function(way) {
67337 for (var i = 0; i < way.nodes.length - 1; i++) {
67338 if (geoEdgeEqual([way.nodes[i], way.nodes[i + 1]], midpoint.edge)) {
67339 graph = graph.replace(graph.entity(way.id).addNode(node.id, i + 1));
67341 // Add only one midpoint on doubled-back segments,
67342 // turning them into self-intersections.
67352 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/AddNodeToWayAction.as
67353 function actionAddVertex(wayId, nodeId, index) {
67354 return function(graph) {
67355 return graph.replace(graph.entity(wayId).addNode(nodeId, index));
67359 function actionChangeMember(relationId, member, memberIndex) {
67360 return function(graph) {
67361 return graph.replace(graph.entity(relationId).updateMember(member, memberIndex));
67365 function actionChangePreset(entityId, oldPreset, newPreset) {
67366 return function(graph) {
67367 var entity = graph.entity(entityId),
67368 geometry = entity.geometry(graph),
67369 tags = entity.tags;
67371 if (oldPreset) tags = oldPreset.removeTags(tags, geometry);
67372 if (newPreset) tags = newPreset.applyTags(tags, geometry);
67374 return graph.replace(entity.update({tags: tags}));
67378 function actionChangeTags(entityId, tags) {
67379 return function(graph) {
67380 var entity = graph.entity(entityId);
67381 return graph.replace(entity.update({tags: tags}));
67385 function actionCircularize(wayId, projection, maxAngle) {
67386 maxAngle = (maxAngle || 20) * Math.PI / 180;
67389 var action = function(graph) {
67390 var way = graph.entity(wayId);
67392 if (!way.isConvex(graph)) {
67393 graph = action.makeConvex(graph);
67396 var nodes = lodash.uniq(graph.childNodes(way)),
67397 keyNodes = nodes.filter(function(n) { return graph.parentWays(n).length !== 1; }),
67398 points = nodes.map(function(n) { return projection(n.loc); }),
67399 keyPoints = keyNodes.map(function(n) { return projection(n.loc); }),
67400 centroid = (points.length === 2) ? geoInterp(points[0], points[1], 0.5) : d3polygonCentroid(points),
67401 radius = median(points, function(p) { return geoEuclideanDistance(centroid, p); }),
67402 sign = d3polygonArea(points) > 0 ? 1 : -1,
67405 // we need atleast two key nodes for the algorithm to work
67406 if (!keyNodes.length) {
67407 keyNodes = [nodes[0]];
67408 keyPoints = [points[0]];
67411 if (keyNodes.length === 1) {
67412 var index = nodes.indexOf(keyNodes[0]),
67413 oppositeIndex = Math.floor((index + nodes.length / 2) % nodes.length);
67415 keyNodes.push(nodes[oppositeIndex]);
67416 keyPoints.push(points[oppositeIndex]);
67419 // key points and nodes are those connected to the ways,
67420 // they are projected onto the circle, inbetween nodes are moved
67421 // to constant intervals between key nodes, extra inbetween nodes are
67422 // added if necessary.
67423 for (var i = 0; i < keyPoints.length; i++) {
67424 var nextKeyNodeIndex = (i + 1) % keyNodes.length,
67425 startNode = keyNodes[i],
67426 endNode = keyNodes[nextKeyNodeIndex],
67427 startNodeIndex = nodes.indexOf(startNode),
67428 endNodeIndex = nodes.indexOf(endNode),
67429 numberNewPoints = -1,
67430 indexRange = endNodeIndex - startNodeIndex,
67431 distance, totalAngle, eachAngle, startAngle, endAngle,
67432 angle, loc, node, j,
67433 inBetweenNodes = [];
67435 if (indexRange < 0) {
67436 indexRange += nodes.length;
67439 // position this key node
67440 distance = geoEuclideanDistance(centroid, keyPoints[i]);
67441 if (distance === 0) { distance = 1e-4; }
67443 centroid[0] + (keyPoints[i][0] - centroid[0]) / distance * radius,
67444 centroid[1] + (keyPoints[i][1] - centroid[1]) / distance * radius];
67445 graph = graph.replace(keyNodes[i].move(projection.invert(keyPoints[i])));
67447 // figure out the between delta angle we want to match to
67448 startAngle = Math.atan2(keyPoints[i][1] - centroid[1], keyPoints[i][0] - centroid[0]);
67449 endAngle = Math.atan2(keyPoints[nextKeyNodeIndex][1] - centroid[1], keyPoints[nextKeyNodeIndex][0] - centroid[0]);
67450 totalAngle = endAngle - startAngle;
67452 // detects looping around -pi/pi
67453 if (totalAngle * sign > 0) {
67454 totalAngle = -sign * (2 * Math.PI - Math.abs(totalAngle));
67459 eachAngle = totalAngle / (indexRange + numberNewPoints);
67460 } while (Math.abs(eachAngle) > maxAngle);
67462 // move existing points
67463 for (j = 1; j < indexRange; j++) {
67464 angle = startAngle + j * eachAngle;
67465 loc = projection.invert([
67466 centroid[0] + Math.cos(angle)*radius,
67467 centroid[1] + Math.sin(angle)*radius]);
67469 node = nodes[(j + startNodeIndex) % nodes.length].move(loc);
67470 graph = graph.replace(node);
67473 // add new inbetween nodes if necessary
67474 for (j = 0; j < numberNewPoints; j++) {
67475 angle = startAngle + (indexRange + j) * eachAngle;
67476 loc = projection.invert([
67477 centroid[0] + Math.cos(angle) * radius,
67478 centroid[1] + Math.sin(angle) * radius]);
67480 node = osmNode({loc: loc});
67481 graph = graph.replace(node);
67483 nodes.splice(endNodeIndex + j, 0, node);
67484 inBetweenNodes.push(node.id);
67487 // Check for other ways that share these keyNodes..
67488 // If keyNodes are adjacent in both ways,
67489 // we can add inBetween nodes to that shared way too..
67490 if (indexRange === 1 && inBetweenNodes.length) {
67491 var startIndex1 = way.nodes.lastIndexOf(startNode.id),
67492 endIndex1 = way.nodes.lastIndexOf(endNode.id),
67493 wayDirection1 = (endIndex1 - startIndex1);
67494 if (wayDirection1 < -1) { wayDirection1 = 1; }
67496 /* eslint-disable no-loop-func */
67497 lodash.each(lodash.without(graph.parentWays(keyNodes[i]), way), function(sharedWay) {
67498 if (sharedWay.areAdjacent(startNode.id, endNode.id)) {
67499 var startIndex2 = sharedWay.nodes.lastIndexOf(startNode.id),
67500 endIndex2 = sharedWay.nodes.lastIndexOf(endNode.id),
67501 wayDirection2 = (endIndex2 - startIndex2),
67502 insertAt = endIndex2;
67503 if (wayDirection2 < -1) { wayDirection2 = 1; }
67505 if (wayDirection1 !== wayDirection2) {
67506 inBetweenNodes.reverse();
67507 insertAt = startIndex2;
67509 for (j = 0; j < inBetweenNodes.length; j++) {
67510 sharedWay = sharedWay.addNode(inBetweenNodes[j], insertAt + j);
67512 graph = graph.replace(sharedWay);
67515 /* eslint-enable no-loop-func */
67520 // update the way to have all the new nodes
67521 ids = nodes.map(function(n) { return n.id; });
67524 way = way.update({nodes: ids});
67525 graph = graph.replace(way);
67531 action.makeConvex = function(graph) {
67532 var way = graph.entity(wayId),
67533 nodes = lodash.uniq(graph.childNodes(way)),
67534 points = nodes.map(function(n) { return projection(n.loc); }),
67535 sign = d3polygonArea(points) > 0 ? 1 : -1,
67536 hull = d3polygonHull(points);
67538 // D3 convex hulls go counterclockwise..
67544 for (var i = 0; i < hull.length - 1; i++) {
67545 var startIndex = points.indexOf(hull[i]),
67546 endIndex = points.indexOf(hull[i+1]),
67547 indexRange = (endIndex - startIndex);
67549 if (indexRange < 0) {
67550 indexRange += nodes.length;
67553 // move interior nodes to the surface of the convex hull..
67554 for (var j = 1; j < indexRange; j++) {
67555 var point = geoInterp(hull[i], hull[i+1], j / indexRange),
67556 node = nodes[(j + startIndex) % nodes.length].move(projection.invert(point));
67557 graph = graph.replace(node);
67564 action.disabled = function(graph) {
67565 if (!graph.entity(wayId).isClosed())
67566 return 'not_closed';
67573 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteWayAction.as
67574 function actionDeleteWay(wayId) {
67577 function canDeleteNode(node, graph) {
67578 return !graph.parentWays(node).length &&
67579 !graph.parentRelations(node).length &&
67580 !node.hasInterestingTags();
67584 var action = function(graph) {
67585 var way = graph.entity(wayId);
67587 graph.parentRelations(way)
67588 .forEach(function(parent) {
67589 parent = parent.removeMembersWithID(wayId);
67590 graph = graph.replace(parent);
67592 if (parent.isDegenerate()) {
67593 graph = actionDeleteRelation(parent.id)(graph);
67597 lodash.uniq(way.nodes).forEach(function(nodeId) {
67598 graph = graph.replace(way.removeNode(nodeId));
67600 var node = graph.entity(nodeId);
67601 if (canDeleteNode(node, graph)) {
67602 graph = graph.remove(node);
67606 return graph.remove(way);
67610 action.disabled = function(graph) {
67611 var disabled = false;
67613 graph.parentRelations(graph.entity(wayId)).forEach(function(parent) {
67614 var type = parent.tags.type,
67615 role = parent.memberById(wayId).role || 'outer';
67616 if (type === 'route' || type === 'boundary' || (type === 'multipolygon' && role === 'outer')) {
67617 disabled = 'part_of_relation';
67628 function actionDeleteMultiple(ids) {
67630 way: actionDeleteWay,
67631 node: actionDeleteNode,
67632 relation: actionDeleteRelation
67636 var action = function(graph) {
67637 ids.forEach(function(id) {
67638 if (graph.hasEntity(id)) { // It may have been deleted aready.
67639 graph = actions[graph.entity(id).type](id)(graph);
67647 action.disabled = function(graph) {
67648 for (var i = 0; i < ids.length; i++) {
67650 disabled = actions[graph.entity(id).type](id).disabled(graph);
67651 if (disabled) return disabled;
67659 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteRelationAction.as
67660 function actionDeleteRelation(relationId) {
67663 function canDeleteEntity(entity, graph) {
67664 return !graph.parentWays(entity).length &&
67665 !graph.parentRelations(entity).length &&
67666 !entity.hasInterestingTags();
67670 var action = function(graph) {
67671 var relation = graph.entity(relationId);
67673 graph.parentRelations(relation)
67674 .forEach(function(parent) {
67675 parent = parent.removeMembersWithID(relationId);
67676 graph = graph.replace(parent);
67678 if (parent.isDegenerate()) {
67679 graph = actionDeleteRelation(parent.id)(graph);
67683 lodash.uniq(lodash.map(relation.members, 'id')).forEach(function(memberId) {
67684 graph = graph.replace(relation.removeMembersWithID(memberId));
67686 var entity = graph.entity(memberId);
67687 if (canDeleteEntity(entity, graph)) {
67688 graph = actionDeleteMultiple([memberId])(graph);
67692 return graph.remove(relation);
67696 action.disabled = function(graph) {
67697 if (!graph.entity(relationId).isComplete(graph))
67698 return 'incomplete_relation';
67705 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteNodeAction.as
67706 function actionDeleteNode(nodeId) {
67707 var action = function(graph) {
67708 var node = graph.entity(nodeId);
67710 graph.parentWays(node)
67711 .forEach(function(parent) {
67712 parent = parent.removeNode(nodeId);
67713 graph = graph.replace(parent);
67715 if (parent.isDegenerate()) {
67716 graph = actionDeleteWay(parent.id)(graph);
67720 graph.parentRelations(node)
67721 .forEach(function(parent) {
67722 parent = parent.removeMembersWithID(nodeId);
67723 graph = graph.replace(parent);
67725 if (parent.isDegenerate()) {
67726 graph = actionDeleteRelation(parent.id)(graph);
67730 return graph.remove(node);
67734 action.disabled = function() {
67742 // Connect the ways at the given nodes.
67744 // The last node will survive. All other nodes will be replaced with
67745 // the surviving node in parent ways, and then removed.
67747 // Tags and relation memberships of of non-surviving nodes are merged
67748 // to the survivor.
67750 // This is the inverse of `iD.actionDisconnect`.
67753 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeNodesAction.as
67754 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/MergeNodesAction.java
67756 function actionConnect(nodeIds) {
67757 return function(graph) {
67758 var survivor = graph.entity(lodash.last(nodeIds));
67760 for (var i = 0; i < nodeIds.length - 1; i++) {
67761 var node = graph.entity(nodeIds[i]);
67763 /* eslint-disable no-loop-func */
67764 graph.parentWays(node).forEach(function(parent) {
67765 if (!parent.areAdjacent(node.id, survivor.id)) {
67766 graph = graph.replace(parent.replaceNode(node.id, survivor.id));
67770 graph.parentRelations(node).forEach(function(parent) {
67771 graph = graph.replace(parent.replaceMember(node, survivor));
67773 /* eslint-enable no-loop-func */
67775 survivor = survivor.mergeTags(node.tags);
67776 graph = actionDeleteNode(node.id)(graph);
67779 graph = graph.replace(survivor);
67785 function actionCopyEntities(ids, fromGraph) {
67789 var action = function(graph) {
67790 ids.forEach(function(id) {
67791 fromGraph.entity(id).copy(fromGraph, copies);
67794 for (var id in copies) {
67795 graph = graph.replace(copies[id]);
67802 action.copies = function() {
67810 function actionDeleteMember(relationId, memberIndex) {
67811 return function(graph) {
67812 var relation = graph.entity(relationId)
67813 .removeMember(memberIndex);
67815 graph = graph.replace(relation);
67817 if (relation.isDegenerate())
67818 graph = actionDeleteRelation(relation.id)(graph);
67824 function actionDeprecateTags(entityId) {
67826 return function(graph) {
67827 var entity = graph.entity(entityId),
67828 newtags = lodash.clone(entity.tags),
67832 // This handles dataDeprecated tags with a single condition
67833 for (var i = 0; i < dataDeprecated.length; i++) {
67835 rule = dataDeprecated[i];
67836 var match = lodash.toPairs(rule.old)[0],
67837 replacements = rule.replace ? lodash.toPairs(rule.replace) : null;
67839 if (entity.tags[match[0]] && match[1] === '*') {
67841 var value = entity.tags[match[0]];
67842 if (replacements && !newtags[replacements[0][0]]) {
67843 newtags[replacements[0][0]] = value;
67845 delete newtags[match[0]];
67848 } else if (entity.tags[match[0]] === match[1]) {
67849 newtags = lodash.assign({}, rule.replace || {}, lodash.omit(newtags, match[0]));
67855 return graph.replace(entity.update({tags: newtags}));
67862 function actionDiscardTags(difference) {
67864 return function(graph) {
67865 function discardTags(entity) {
67866 if (!lodash.isEmpty(entity.tags)) {
67868 lodash.each(entity.tags, function(v, k) {
67869 if (v) tags[k] = v;
67872 graph = graph.replace(entity.update({
67873 tags: lodash.omit(tags, dataDiscarded)
67878 difference.modified().forEach(discardTags);
67879 difference.created().forEach(discardTags);
67885 // Disconect the ways at the given node.
67887 // Optionally, disconnect only the given ways.
67889 // For testing convenience, accepts an ID to assign to the (first) new node.
67890 // Normally, this will be undefined and the way will automatically
67891 // be assigned a new ID.
67893 // This is the inverse of `iD.actionConnect`.
67896 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/UnjoinNodeAction.as
67897 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/UnGlueAction.java
67899 function actionDisconnect(nodeId, newNodeId) {
67903 var action = function(graph) {
67904 var node = graph.entity(nodeId),
67905 connections = action.connections(graph);
67907 connections.forEach(function(connection) {
67908 var way = graph.entity(connection.wayID),
67909 newNode = osmNode({id: newNodeId, loc: node.loc, tags: node.tags});
67911 graph = graph.replace(newNode);
67912 if (connection.index === 0 && way.isArea()) {
67913 // replace shared node with shared node..
67914 graph = graph.replace(way.replaceNode(way.nodes[0], newNode.id));
67916 // replace shared node with multiple new nodes..
67917 graph = graph.replace(way.updateNode(newNode.id, connection.index));
67925 action.connections = function(graph) {
67926 var candidates = [],
67928 parentWays = graph.parentWays(graph.entity(nodeId));
67930 parentWays.forEach(function(way) {
67931 if (wayIds && wayIds.indexOf(way.id) === -1) {
67935 if (way.isArea() && (way.nodes[0] === nodeId)) {
67936 candidates.push({wayID: way.id, index: 0});
67938 way.nodes.forEach(function(waynode, index) {
67939 if (waynode === nodeId) {
67940 candidates.push({wayID: way.id, index: index});
67946 return keeping ? candidates : candidates.slice(1);
67950 action.disabled = function(graph) {
67951 var connections = action.connections(graph);
67952 if (connections.length === 0 || (wayIds && wayIds.length !== connections.length))
67953 return 'not_connected';
67955 var parentWays = graph.parentWays(graph.entity(nodeId)),
67956 seenRelationIds = {},
67959 parentWays.forEach(function(way) {
67960 if (wayIds && wayIds.indexOf(way.id) === -1)
67963 var relations = graph.parentRelations(way);
67964 relations.forEach(function(relation) {
67965 if (relation.id in seenRelationIds) {
67966 sharedRelation = relation;
67968 seenRelationIds[relation.id] = true;
67973 if (sharedRelation)
67978 action.limitWays = function(_) {
67979 if (!arguments.length) return wayIds;
67988 // Join ways at the end node they share.
67990 // This is the inverse of `iD.actionSplit`.
67993 // https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeWaysAction.as
67994 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/CombineWayAction.java
67996 function actionJoin(ids) {
67998 function groupEntitiesByGeometry(graph) {
67999 var entities = ids.map(function(id) { return graph.entity(id); });
68000 return lodash.extend({line: []}, lodash.groupBy(entities, function(entity) { return entity.geometry(graph); }));
68004 var action = function(graph) {
68005 var ways = ids.map(graph.entity, graph),
68006 survivor = ways[0];
68008 // Prefer to keep an existing way.
68009 for (var i = 0; i < ways.length; i++) {
68010 if (!ways[i].isNew()) {
68011 survivor = ways[i];
68016 var joined = osmJoinWays(ways, graph)[0];
68018 survivor = survivor.update({nodes: lodash.map(joined.nodes, 'id')});
68019 graph = graph.replace(survivor);
68021 joined.forEach(function(way) {
68022 if (way.id === survivor.id)
68025 graph.parentRelations(way).forEach(function(parent) {
68026 graph = graph.replace(parent.replaceMember(way, survivor));
68029 survivor = survivor.mergeTags(way.tags);
68031 graph = graph.replace(survivor);
68032 graph = actionDeleteWay(way.id)(graph);
68039 action.disabled = function(graph) {
68040 var geometries = groupEntitiesByGeometry(graph);
68041 if (ids.length < 2 || ids.length !== geometries.line.length)
68042 return 'not_eligible';
68044 var joined = osmJoinWays(ids.map(graph.entity, graph), graph);
68045 if (joined.length > 1)
68046 return 'not_adjacent';
68048 var nodeIds = lodash.map(joined[0].nodes, 'id').slice(1, -1),
68051 conflicting = false;
68053 joined[0].forEach(function(way) {
68054 var parents = graph.parentRelations(way);
68055 parents.forEach(function(parent) {
68056 if (parent.isRestriction() && parent.members.some(function(m) { return nodeIds.indexOf(m.id) >= 0; }))
68060 for (var k in way.tags) {
68061 if (!(k in tags)) {
68062 tags[k] = way.tags[k];
68063 } else if (tags[k] && osmIsInterestingTag(k) && tags[k] !== way.tags[k]) {
68064 conflicting = true;
68070 return 'restriction';
68073 return 'conflicting_tags';
68080 function actionMerge(ids) {
68082 function groupEntitiesByGeometry(graph) {
68083 var entities = ids.map(function(id) { return graph.entity(id); });
68084 return lodash.extend({point: [], area: [], line: [], relation: []},
68085 lodash.groupBy(entities, function(entity) { return entity.geometry(graph); }));
68089 var action = function(graph) {
68090 var geometries = groupEntitiesByGeometry(graph),
68091 target = geometries.area[0] || geometries.line[0],
68092 points = geometries.point;
68094 points.forEach(function(point) {
68095 target = target.mergeTags(point.tags);
68097 graph.parentRelations(point).forEach(function(parent) {
68098 graph = graph.replace(parent.replaceMember(point, target));
68101 graph = graph.remove(point);
68104 graph = graph.replace(target);
68110 action.disabled = function(graph) {
68111 var geometries = groupEntitiesByGeometry(graph);
68112 if (geometries.point.length === 0 ||
68113 (geometries.area.length + geometries.line.length) !== 1 ||
68114 geometries.relation.length !== 0)
68115 return 'not_eligible';
68122 function actionMergePolygon(ids, newRelationId) {
68124 function groupEntities(graph) {
68125 var entities = ids.map(function (id) { return graph.entity(id); });
68126 return lodash.extend({
68130 }, lodash.groupBy(entities, function(entity) {
68131 if (entity.type === 'way' && entity.isClosed()) {
68132 return 'closedWay';
68133 } else if (entity.type === 'relation' && entity.isMultipolygon()) {
68134 return 'multipolygon';
68142 var action = function(graph) {
68143 var entities = groupEntities(graph);
68145 // An array representing all the polygons that are part of the multipolygon.
68147 // Each element is itself an array of objects with an id property, and has a
68148 // locs property which is an array of the locations forming the polygon.
68149 var polygons = entities.multipolygon.reduce(function(polygons, m) {
68150 return polygons.concat(osmJoinWays(m.members, graph));
68151 }, []).concat(entities.closedWay.map(function(d) {
68152 var member = [{id: d.id}];
68153 member.nodes = graph.childNodes(d);
68157 // contained is an array of arrays of boolean values,
68158 // where contained[j][k] is true iff the jth way is
68159 // contained by the kth way.
68160 var contained = polygons.map(function(w, i) {
68161 return polygons.map(function(d, n) {
68162 if (i === n) return null;
68163 return geoPolygonContainsPolygon(
68164 lodash.map(d.nodes, 'loc'),
68165 lodash.map(w.nodes, 'loc'));
68169 // Sort all polygons as either outer or inner ways
68173 while (polygons.length) {
68174 extractUncontained(polygons);
68175 polygons = polygons.filter(isContained);
68176 contained = contained.filter(isContained).map(filterContained);
68179 function isContained(d, i) {
68180 return lodash.some(contained[i]);
68183 function filterContained(d) {
68184 return d.filter(isContained);
68187 function extractUncontained(polygons) {
68188 polygons.forEach(function(d, i) {
68189 if (!isContained(d, i)) {
68190 d.forEach(function(member) {
68194 role: outer ? 'outer' : 'inner'
68202 // Move all tags to one relation
68203 var relation = entities.multipolygon[0] ||
68204 osmRelation({ id: newRelationId, tags: { type: 'multipolygon' }});
68206 entities.multipolygon.slice(1).forEach(function(m) {
68207 relation = relation.mergeTags(m.tags);
68208 graph = graph.remove(m);
68211 entities.closedWay.forEach(function(way) {
68212 function isThisOuter(m) {
68213 return m.id === way.id && m.role !== 'inner';
68215 if (members.some(isThisOuter)) {
68216 relation = relation.mergeTags(way.tags);
68217 graph = graph.replace(way.update({ tags: {} }));
68221 return graph.replace(relation.update({
68223 tags: lodash.omit(relation.tags, 'area')
68228 action.disabled = function(graph) {
68229 var entities = groupEntities(graph);
68230 if (entities.other.length > 0 ||
68231 entities.closedWay.length + entities.multipolygon.length < 2)
68232 return 'not_eligible';
68233 if (!entities.multipolygon.every(function(r) { return r.isComplete(graph); }))
68234 return 'incomplete_relation';
68241 // Copyright (c) 2006, 2008 Tony Garnock-Jones <tonyg@lshift.net>
68242 // Copyright (c) 2006, 2008 LShift Ltd. <query@lshift.net>
68244 // Permission is hereby granted, free of charge, to any person
68245 // obtaining a copy of this software and associated documentation files
68246 // (the "Software"), to deal in the Software without restriction,
68247 // including without limitation the rights to use, copy, modify, merge,
68248 // publish, distribute, sublicense, and/or sell copies of the Software,
68249 // and to permit persons to whom the Software is furnished to do so,
68250 // subject to the following conditions:
68252 // The above copyright notice and this permission notice shall be
68253 // included in all copies or substantial portions of the Software.
68255 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
68256 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
68257 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
68258 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
68259 // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
68260 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
68261 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
68264 // source: https://bitbucket.org/lshift/synchrotron/src
68265 function longest_common_subsequence(file1, file2) {
68266 /* Text diff algorithm following Hunt and McIlroy 1976.
68267 * J. W. Hunt and M. D. McIlroy, An algorithm for differential file
68268 * comparison, Bell Telephone Laboratories CSTR #41 (1976)
68269 * http://www.cs.dartmouth.edu/~doug/
68271 * Expects two arrays of strings.
68273 var equivalenceClasses;
68278 var c, i, j, jX, r, s;
68280 equivalenceClasses = {};
68281 for (j = 0; j < file2.length; j++) {
68283 if (equivalenceClasses[line]) {
68284 equivalenceClasses[line].push(j);
68286 equivalenceClasses[line] = [j];
68290 candidates = [{file1index: -1,
68294 for (i = 0; i < file1.length; i++) {
68296 file2indices = equivalenceClasses[line] || [];
68301 for (jX = 0; jX < file2indices.length; jX++) {
68302 j = file2indices[jX];
68304 for (s = 0; s < candidates.length; s++) {
68305 if ((candidates[s].file2index < j) &&
68306 ((s === candidates.length - 1) ||
68307 (candidates[s + 1].file2index > j)))
68311 if (s < candidates.length) {
68312 newCandidate = {file1index: i,
68314 chain: candidates[s]};
68315 if (r === candidates.length) {
68316 candidates.push(c);
68322 if (r === candidates.length) {
68323 break; // no point in examining further (j)s
68331 // At this point, we know the LCS: it's in the reverse of the
68332 // linked-list through .chain of
68333 // candidates[candidates.length - 1].
68335 return candidates[candidates.length - 1];
68348 function diff_indices(file1, file2) {
68349 // We apply the LCS to give a simple representation of the
68350 // offsets and lengths of mismatched chunks in the input
68351 // files. This is used by diff3_merge_indices below.
68354 var tail1 = file1.length;
68355 var tail2 = file2.length;
68357 for (var candidate = longest_common_subsequence(file1, file2);
68358 candidate !== null;
68359 candidate = candidate.chain)
68361 var mismatchLength1 = tail1 - candidate.file1index - 1;
68362 var mismatchLength2 = tail2 - candidate.file2index - 1;
68363 tail1 = candidate.file1index;
68364 tail2 = candidate.file2index;
68366 if (mismatchLength1 || mismatchLength2) {
68367 result.push({file1: [tail1 + 1, mismatchLength1],
68368 file2: [tail2 + 1, mismatchLength2]});
68376 function diff3_merge_indices (a, o, b) {
68377 // Given three files, A, O, and B, where both A and B are
68378 // independently derived from O, returns a fairly complicated
68379 // internal representation of merge decisions it's taken. The
68380 // interested reader may wish to consult
68382 // Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce. "A
68383 // Formal Investigation of Diff3." In Arvind and Prasad,
68384 // editors, Foundations of Software Technology and Theoretical
68385 // Computer Science (FSTTCS), December 2007.
68387 // (http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf)
68390 var m1 = diff_indices(o, a);
68391 var m2 = diff_indices(o, b);
68394 function addHunk(h, side) {
68395 hunks.push([h.file1[0], side, h.file1[1], h.file2[0], h.file2[1]]);
68397 for (i = 0; i < m1.length; i++) { addHunk(m1[i], 0); }
68398 for (i = 0; i < m2.length; i++) { addHunk(m2[i], 2); }
68402 var commonOffset = 0;
68403 function copyCommon(targetOffset) {
68404 if (targetOffset > commonOffset) {
68405 result.push([1, commonOffset, targetOffset - commonOffset]);
68406 commonOffset = targetOffset;
68410 for (var hunkIndex = 0; hunkIndex < hunks.length; hunkIndex++) {
68411 var firstHunkIndex = hunkIndex;
68412 var hunk = hunks[hunkIndex];
68413 var regionLhs = hunk[0];
68414 var regionRhs = regionLhs + hunk[2];
68415 while (hunkIndex < hunks.length - 1) {
68416 var maybeOverlapping = hunks[hunkIndex + 1];
68417 var maybeLhs = maybeOverlapping[0];
68418 if (maybeLhs > regionRhs) break;
68419 regionRhs = maybeLhs + maybeOverlapping[2];
68423 copyCommon(regionLhs);
68424 if (firstHunkIndex === hunkIndex) {
68425 // The "overlap" was only one hunk long, meaning that
68426 // there's no conflict here. Either a and o were the
68427 // same, or b and o were the same.
68429 result.push([hunk[1], hunk[3], hunk[4]]);
68432 // A proper conflict. Determine the extents of the
68433 // regions involved from a, o and b. Effectively merge
68434 // all the hunks on the left into one giant hunk, and
68435 // do the same for the right; then, correct for skew
68436 // in the regions of o that each side changed, and
68437 // report appropriate spans for the three sides.
68439 0: [a.length, -1, o.length, -1],
68440 2: [b.length, -1, o.length, -1]
68442 for (i = firstHunkIndex; i <= hunkIndex; i++) {
68444 var side = hunk[1];
68445 var r = regions[side];
68446 var oLhs = hunk[0];
68447 var oRhs = oLhs + hunk[2];
68448 var abLhs = hunk[3];
68449 var abRhs = abLhs + hunk[4];
68450 r[0] = Math.min(abLhs, r[0]);
68451 r[1] = Math.max(abRhs, r[1]);
68452 r[2] = Math.min(oLhs, r[2]);
68453 r[3] = Math.max(oRhs, r[3]);
68455 var aLhs = regions[0][0] + (regionLhs - regions[0][2]);
68456 var aRhs = regions[0][1] + (regionRhs - regions[0][3]);
68457 var bLhs = regions[2][0] + (regionLhs - regions[2][2]);
68458 var bRhs = regions[2][1] + (regionRhs - regions[2][3]);
68461 regionLhs, regionRhs - regionLhs,
68462 bLhs, bRhs - bLhs]);
68464 commonOffset = regionRhs;
68467 copyCommon(o.length);
68471 function diff3_merge (a, o, b, excludeFalseConflicts) {
68472 // Applies the output of Diff3.diff3_merge_indices to actually
68473 // construct the merged file; the returned result alternates
68474 // between "ok" and "conflict" blocks.
68477 var files = [a, o, b];
68478 var indices = diff3_merge_indices(a, o, b);
68481 function flushOk() {
68482 if (okLines.length) {
68483 result.push({ok: okLines});
68487 function pushOk(xs) {
68488 for (var j = 0; j < xs.length; j++) {
68489 okLines.push(xs[j]);
68493 function isTrueConflict(rec) {
68494 if (rec[2] !== rec[6]) return true;
68497 for (var j = 0; j < rec[2]; j++) {
68498 if (a[j + aoff] !== b[j + boff]) return true;
68503 for (var i = 0; i < indices.length; i++) {
68504 var x = indices[i];
68507 if (excludeFalseConflicts && !isTrueConflict(x)) {
68508 pushOk(files[0].slice(x[1], x[1] + x[2]));
68511 result.push({conflict: {a: a.slice(x[1], x[1] + x[2]),
68513 o: o.slice(x[3], x[3] + x[4]),
68515 b: b.slice(x[5], x[5] + x[6]),
68519 pushOk(files[side].slice(x[1], x[1] + x[2]));
68527 function actionMergeRemoteChanges(id, localGraph, remoteGraph, formatUser) {
68528 var option = 'safe', // 'safe', 'force_local', 'force_remote'
68533 return lodash.isFunction(formatUser) ? formatUser(d) : d;
68537 function mergeLocation(remote, target) {
68538 function pointEqual(a, b) {
68539 var epsilon = 1e-6;
68540 return (Math.abs(a[0] - b[0]) < epsilon) && (Math.abs(a[1] - b[1]) < epsilon);
68543 if (option === 'force_local' || pointEqual(target.loc, remote.loc)) {
68546 if (option === 'force_remote') {
68547 return target.update({loc: remote.loc});
68550 conflicts.push(t('merge_remote_changes.conflict.location', { user: user(remote.user) }));
68555 function mergeNodes(base, remote, target) {
68556 if (option === 'force_local' || lodash.isEqual(target.nodes, remote.nodes)) {
68559 if (option === 'force_remote') {
68560 return target.update({nodes: remote.nodes});
68563 var ccount = conflicts.length,
68564 o = base.nodes || [],
68565 a = target.nodes || [],
68566 b = remote.nodes || [],
68568 hunks = diff3_merge(a, o, b, true);
68570 for (var i = 0; i < hunks.length; i++) {
68571 var hunk = hunks[i];
68573 nodes.push.apply(nodes, hunk.ok);
68575 // for all conflicts, we can assume c.a !== c.b
68576 // because `diff3_merge` called with `true` option to exclude false conflicts..
68577 var c = hunk.conflict;
68578 if (lodash.isEqual(c.o, c.a)) { // only changed remotely
68579 nodes.push.apply(nodes, c.b);
68580 } else if (lodash.isEqual(c.o, c.b)) { // only changed locally
68581 nodes.push.apply(nodes, c.a);
68582 } else { // changed both locally and remotely
68583 conflicts.push(t('merge_remote_changes.conflict.nodelist', { user: user(remote.user) }));
68589 return (conflicts.length === ccount) ? target.update({nodes: nodes}) : target;
68593 function mergeChildren(targetWay, children, updates, graph) {
68594 function isUsed(node, targetWay) {
68595 var parentWays = lodash.map(graph.parentWays(node), 'id');
68596 return node.hasInterestingTags() ||
68597 lodash.without(parentWays, targetWay.id).length > 0 ||
68598 graph.parentRelations(node).length > 0;
68601 var ccount = conflicts.length;
68603 for (var i = 0; i < children.length; i++) {
68604 var id = children[i],
68605 node = graph.hasEntity(id);
68607 // remove unused childNodes..
68608 if (targetWay.nodes.indexOf(id) === -1) {
68609 if (node && !isUsed(node, targetWay)) {
68610 updates.removeIds.push(id);
68615 // restore used childNodes..
68616 var local = localGraph.hasEntity(id),
68617 remote = remoteGraph.hasEntity(id),
68620 if (option === 'force_remote' && remote && remote.visible) {
68621 updates.replacements.push(remote);
68623 } else if (option === 'force_local' && local) {
68624 target = osmEntity$$1(local);
68626 target = target.update({ version: remote.version });
68628 updates.replacements.push(target);
68630 } else if (option === 'safe' && local && remote && local.version !== remote.version) {
68631 target = osmEntity$$1(local, { version: remote.version });
68632 if (remote.visible) {
68633 target = mergeLocation(remote, target);
68635 conflicts.push(t('merge_remote_changes.conflict.deleted', { user: user(remote.user) }));
68638 if (conflicts.length !== ccount) break;
68639 updates.replacements.push(target);
68647 function updateChildren(updates, graph) {
68648 for (var i = 0; i < updates.replacements.length; i++) {
68649 graph = graph.replace(updates.replacements[i]);
68651 if (updates.removeIds.length) {
68652 graph = actionDeleteMultiple(updates.removeIds)(graph);
68658 function mergeMembers(remote, target) {
68659 if (option === 'force_local' || lodash.isEqual(target.members, remote.members)) {
68662 if (option === 'force_remote') {
68663 return target.update({members: remote.members});
68666 conflicts.push(t('merge_remote_changes.conflict.memberlist', { user: user(remote.user) }));
68671 function mergeTags(base, remote, target) {
68672 function ignoreKey(k) {
68673 return lodash.includes(dataDiscarded, k);
68676 if (option === 'force_local' || lodash.isEqual(target.tags, remote.tags)) {
68679 if (option === 'force_remote') {
68680 return target.update({tags: remote.tags});
68683 var ccount = conflicts.length,
68684 o = base.tags || {},
68685 a = target.tags || {},
68686 b = remote.tags || {},
68687 keys = lodash.reject(lodash.union(lodash.keys(o), lodash.keys(a), lodash.keys(b)), ignoreKey),
68688 tags = lodash.clone(a),
68691 for (var i = 0; i < keys.length; i++) {
68694 if (o[k] !== b[k] && a[k] !== b[k]) { // changed remotely..
68695 if (o[k] !== a[k]) { // changed locally..
68696 conflicts.push(t('merge_remote_changes.conflict.tags',
68697 { tag: k, local: a[k], remote: b[k], user: user(remote.user) }));
68699 } else { // unchanged locally, accept remote change..
68700 if (b.hasOwnProperty(k)) {
68710 return (changed && conflicts.length === ccount) ? target.update({tags: tags}) : target;
68714 // `graph.base()` is the common ancestor of the two graphs.
68715 // `localGraph` contains user's edits up to saving
68716 // `remoteGraph` contains remote edits to modified nodes
68717 // `graph` must be a descendent of `localGraph` and may include
68718 // some conflict resolution actions performed on it.
68720 // --- ... --- `localGraph` -- ... -- `graph`
68722 // `graph.base()` --- ... --- `remoteGraph`
68724 var action = function(graph) {
68725 var updates = { replacements: [], removeIds: [] },
68726 base = graph.base().entities[id],
68727 local = localGraph.entity(id),
68728 remote = remoteGraph.entity(id),
68729 target = osmEntity$$1(local, { version: remote.version });
68732 if (!remote.visible) {
68733 if (option === 'force_remote') {
68734 return actionDeleteMultiple([id])(graph);
68736 } else if (option === 'force_local') {
68737 if (target.type === 'way') {
68738 target = mergeChildren(target, lodash.uniq(local.nodes), updates, graph);
68739 graph = updateChildren(updates, graph);
68741 return graph.replace(target);
68744 conflicts.push(t('merge_remote_changes.conflict.deleted', { user: user(remote.user) }));
68745 return graph; // do nothing
68750 if (target.type === 'node') {
68751 target = mergeLocation(remote, target);
68753 } else if (target.type === 'way') {
68754 // pull in any child nodes that may not be present locally..
68755 graph.rebase(remoteGraph.childNodes(remote), [graph], false);
68756 target = mergeNodes(base, remote, target);
68757 target = mergeChildren(target, lodash.union(local.nodes, remote.nodes), updates, graph);
68759 } else if (target.type === 'relation') {
68760 target = mergeMembers(remote, target);
68763 target = mergeTags(base, remote, target);
68765 if (!conflicts.length) {
68766 graph = updateChildren(updates, graph).replace(target);
68773 action.withOption = function(opt) {
68779 action.conflicts = function() {
68787 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/command/MoveCommand.java
68788 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MoveNodeAction.as
68789 function actionMove(moveIds, tryDelta, projection, cache) {
68790 var delta = tryDelta;
68792 function vecAdd(a, b) { return [a[0] + b[0], a[1] + b[1]]; }
68793 function vecSub(a, b) { return [a[0] - b[0], a[1] - b[1]]; }
68795 function setupCache(graph) {
68796 function canMove(nodeId) {
68797 // Allow movement of any node that is in the selectedIDs list..
68798 if (moveIds.indexOf(nodeId) !== -1) return true;
68800 // Allow movement of a vertex where 2 ways meet..
68801 var parents = lodash.map(graph.parentWays(graph.entity(nodeId)), 'id');
68802 if (parents.length < 3) return true;
68804 // Restrict movement of a vertex where >2 ways meet, unless all parentWays are moving too..
68805 var parentsMoving = lodash.every(parents, function(id) { return cache.moving[id]; });
68806 if (!parentsMoving) delete cache.moving[nodeId];
68808 return parentsMoving;
68811 function cacheEntities(ids) {
68812 ids.forEach(function(id) {
68813 if (cache.moving[id]) return;
68814 cache.moving[id] = true;
68816 var entity = graph.hasEntity(id);
68817 if (!entity) return;
68819 if (entity.type === 'node') {
68820 cache.nodes.push(id);
68821 cache.startLoc[id] = entity.loc;
68822 } else if (entity.type === 'way') {
68823 cache.ways.push(id);
68824 cacheEntities(entity.nodes);
68826 cacheEntities(entity.members.map(function(member) {
68833 function cacheIntersections(ids) {
68834 function isEndpoint(way, id) { return !way.isClosed() && !!way.affix(id); }
68836 ids.forEach(function(id) {
68837 // consider only intersections with 1 moved and 1 unmoved way.
68838 var childNodes = graph.childNodes(graph.entity(id));
68839 childNodes.forEach(function(node) {
68840 var parents = graph.parentWays(node);
68841 if (parents.length !== 2) return;
68843 var moved = graph.entity(id),
68844 unmoved = lodash.find(parents, function(way) { return !cache.moving[way.id]; });
68845 if (!unmoved) return;
68847 // exclude ways that are overly connected..
68848 if (lodash.intersection(moved.nodes, unmoved.nodes).length > 2) return;
68850 if (moved.isArea() || unmoved.isArea()) return;
68852 cache.intersection[node.id] = {
68855 unmovedId: unmoved.id,
68856 movedIsEP: isEndpoint(moved, node.id),
68857 unmovedIsEP: isEndpoint(unmoved, node.id)
68869 cache.intersection = {};
68870 cache.replacedVertex = {};
68871 cache.startLoc = {};
68875 cacheEntities(moveIds);
68876 cacheIntersections(cache.ways);
68877 cache.nodes = lodash.filter(cache.nodes, canMove);
68884 // Place a vertex where the moved vertex used to be, to preserve way shape..
68885 function replaceMovedVertex(nodeId, wayId, graph, delta) {
68886 var way = graph.entity(wayId),
68887 moved = graph.entity(nodeId),
68888 movedIndex = way.nodes.indexOf(nodeId),
68889 len, prevIndex, nextIndex;
68891 if (way.isClosed()) {
68892 len = way.nodes.length - 1;
68893 prevIndex = (movedIndex + len - 1) % len;
68894 nextIndex = (movedIndex + len + 1) % len;
68896 len = way.nodes.length;
68897 prevIndex = movedIndex - 1;
68898 nextIndex = movedIndex + 1;
68901 var prev = graph.hasEntity(way.nodes[prevIndex]),
68902 next = graph.hasEntity(way.nodes[nextIndex]);
68904 // Don't add orig vertex at endpoint..
68905 if (!prev || !next) return graph;
68907 var key = wayId + '_' + nodeId,
68908 orig = cache.replacedVertex[key];
68911 cache.replacedVertex[key] = orig;
68912 cache.startLoc[orig.id] = cache.startLoc[nodeId];
68917 start = projection(cache.startLoc[nodeId]);
68918 end = projection.invert(vecAdd(start, delta));
68920 end = cache.startLoc[nodeId];
68922 orig = orig.move(end);
68924 var angle = Math.abs(geoAngle(orig, prev, projection) -
68925 geoAngle(orig, next, projection)) * 180 / Math.PI;
68927 // Don't add orig vertex if it would just make a straight line..
68928 if (angle > 175 && angle < 185) return graph;
68930 // Don't add orig vertex if another point is already nearby (within 10m)
68931 if (geoSphericalDistance(prev.loc, orig.loc) < 10 ||
68932 geoSphericalDistance(orig.loc, next.loc) < 10) return graph;
68934 // moving forward or backward along way?
68935 var p1 = [prev.loc, orig.loc, moved.loc, next.loc].map(projection),
68936 p2 = [prev.loc, moved.loc, orig.loc, next.loc].map(projection),
68937 d1 = geoPathLength(p1),
68938 d2 = geoPathLength(p2),
68939 insertAt = (d1 < d2) ? movedIndex : nextIndex;
68941 // moving around closed loop?
68942 if (way.isClosed() && insertAt === 0) insertAt = len;
68944 way = way.addNode(orig.id, insertAt);
68945 return graph.replace(orig).replace(way);
68949 // Reorder nodes around intersections that have moved..
68950 function unZorroIntersection(intersection, graph) {
68951 var vertex = graph.entity(intersection.nodeId),
68952 way1 = graph.entity(intersection.movedId),
68953 way2 = graph.entity(intersection.unmovedId),
68954 isEP1 = intersection.movedIsEP,
68955 isEP2 = intersection.unmovedIsEP;
68957 // don't move the vertex if it is the endpoint of both ways.
68958 if (isEP1 && isEP2) return graph;
68960 var nodes1 = lodash.without(graph.childNodes(way1), vertex),
68961 nodes2 = lodash.without(graph.childNodes(way2), vertex);
68963 if (way1.isClosed() && way1.first() === vertex.id) nodes1.push(nodes1[0]);
68964 if (way2.isClosed() && way2.first() === vertex.id) nodes2.push(nodes2[0]);
68966 var edge1 = !isEP1 && geoChooseEdge(nodes1, projection(vertex.loc), projection),
68967 edge2 = !isEP2 && geoChooseEdge(nodes2, projection(vertex.loc), projection),
68970 // snap vertex to nearest edge (or some point between them)..
68971 if (!isEP1 && !isEP2) {
68972 var epsilon = 1e-4, maxIter = 10;
68973 for (var i = 0; i < maxIter; i++) {
68974 loc = geoInterp(edge1.loc, edge2.loc, 0.5);
68975 edge1 = geoChooseEdge(nodes1, projection(loc), projection);
68976 edge2 = geoChooseEdge(nodes2, projection(loc), projection);
68977 if (Math.abs(edge1.distance - edge2.distance) < epsilon) break;
68979 } else if (!isEP1) {
68985 graph = graph.replace(vertex.move(loc));
68987 // if zorro happened, reorder nodes..
68988 if (!isEP1 && edge1.index !== way1.nodes.indexOf(vertex.id)) {
68989 way1 = way1.removeNode(vertex.id).addNode(vertex.id, edge1.index);
68990 graph = graph.replace(way1);
68992 if (!isEP2 && edge2.index !== way2.nodes.indexOf(vertex.id)) {
68993 way2 = way2.removeNode(vertex.id).addNode(vertex.id, edge2.index);
68994 graph = graph.replace(way2);
69001 function cleanupIntersections(graph) {
69002 lodash.each(cache.intersection, function(obj) {
69003 graph = replaceMovedVertex(obj.nodeId, obj.movedId, graph, delta);
69004 graph = replaceMovedVertex(obj.nodeId, obj.unmovedId, graph, null);
69005 graph = unZorroIntersection(obj, graph);
69012 // check if moving way endpoint can cross an unmoved way, if so limit delta..
69013 function limitDelta(graph) {
69014 lodash.each(cache.intersection, function(obj) {
69015 // Don't limit movement if this is vertex joins 2 endpoints..
69016 if (obj.movedIsEP && obj.unmovedIsEP) return;
69017 // Don't limit movement if this vertex is not an endpoint anyway..
69018 if (!obj.movedIsEP) return;
69020 var node = graph.entity(obj.nodeId),
69021 start = projection(node.loc),
69022 end = vecAdd(start, delta),
69023 movedNodes = graph.childNodes(graph.entity(obj.movedId)),
69024 movedPath = lodash.map(lodash.map(movedNodes, 'loc'),
69025 function(loc) { return vecAdd(projection(loc), delta); }),
69026 unmovedNodes = graph.childNodes(graph.entity(obj.unmovedId)),
69027 unmovedPath = lodash.map(lodash.map(unmovedNodes, 'loc'), projection),
69028 hits = geoPathIntersections(movedPath, unmovedPath);
69030 for (var i = 0; i < hits.length; i++) {
69031 if (lodash.isEqual(hits[i], end)) continue;
69032 var edge = geoChooseEdge(unmovedNodes, end, projection);
69033 delta = vecSub(projection(edge.loc), start);
69039 var action = function(graph) {
69040 if (delta[0] === 0 && delta[1] === 0) return graph;
69044 if (!lodash.isEmpty(cache.intersection)) {
69048 lodash.each(cache.nodes, function(id) {
69049 var node = graph.entity(id),
69050 start = projection(node.loc),
69051 end = vecAdd(start, delta);
69052 graph = graph.replace(node.move(projection.invert(end)));
69055 if (!lodash.isEmpty(cache.intersection)) {
69056 graph = cleanupIntersections(graph);
69063 action.disabled = function(graph) {
69064 function incompleteRelation(id) {
69065 var entity = graph.entity(id);
69066 return entity.type === 'relation' && !entity.isComplete(graph);
69069 if (lodash.some(moveIds, incompleteRelation))
69070 return 'incomplete_relation';
69074 action.delta = function() {
69082 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/command/MoveCommand.java
69083 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MoveNodeAction.as
69084 function actionMoveNode(nodeId, loc) {
69085 return function(graph) {
69086 return graph.replace(graph.entity(nodeId).move(loc));
69090 function actionNoop() {
69091 return function(graph) {
69097 * Based on https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/potlatch2/tools/Quadrilateralise.as
69099 function actionOrthogonalize(wayId, projection) {
69100 var threshold = 12, // degrees within right or straight to alter
69101 lowerThreshold = Math.cos((90 - threshold) * Math.PI / 180),
69102 upperThreshold = Math.cos(threshold * Math.PI / 180);
69105 var action = function(graph) {
69106 var way = graph.entity(wayId),
69107 nodes = graph.childNodes(way),
69108 points = lodash.uniq(nodes).map(function(n) { return projection(n.loc); }),
69109 corner = {i: 0, dotp: 1},
69111 i, j, score, motions;
69113 if (nodes.length === 4) {
69114 for (i = 0; i < 1000; i++) {
69115 motions = points.map(calcMotion);
69116 points[corner.i] = addPoints(points[corner.i],motions[corner.i]);
69117 score = corner.dotp;
69118 if (score < epsilon) {
69123 graph = graph.replace(graph.entity(nodes[corner.i].id)
69124 .move(projection.invert(points[corner.i])));
69128 originalPoints = lodash.clone(points);
69131 for (i = 0; i < 1000; i++) {
69132 motions = points.map(calcMotion);
69133 for (j = 0; j < motions.length; j++) {
69134 points[j] = addPoints(points[j],motions[j]);
69136 var newScore = squareness(points);
69137 if (newScore < score) {
69138 best = lodash.clone(points);
69141 if (score < epsilon) {
69148 for (i = 0; i < points.length; i++) {
69149 // only move the points that actually moved
69150 if (originalPoints[i][0] !== points[i][0] || originalPoints[i][1] !== points[i][1]) {
69151 graph = graph.replace(graph.entity(nodes[i].id)
69152 .move(projection.invert(points[i])));
69156 // remove empty nodes on straight sections
69157 for (i = 0; i < points.length; i++) {
69158 var node = nodes[i];
69160 if (graph.parentWays(node).length > 1 ||
69161 graph.parentRelations(node).length ||
69162 node.hasInterestingTags()) {
69167 var dotp = normalizedDotProduct(i, points);
69168 if (dotp < -1 + epsilon) {
69169 graph = actionDeleteNode(nodes[i].id)(graph);
69177 function calcMotion(b, i, array) {
69178 var a = array[(i - 1 + array.length) % array.length],
69179 c = array[(i + 1) % array.length],
69180 p = subtractPoints(a, b),
69181 q = subtractPoints(c, b),
69184 scale = 2 * Math.min(geoEuclideanDistance(p, [0, 0]), geoEuclideanDistance(q, [0, 0]));
69185 p = normalizePoint(p, 1.0);
69186 q = normalizePoint(q, 1.0);
69188 dotp = filterDotProduct(p[0] * q[0] + p[1] * q[1]);
69190 // nasty hack to deal with almost-straight segments (angle is closer to 180 than to 90/270).
69191 if (array.length > 3) {
69192 if (dotp < -0.707106781186547) {
69195 } else if (dotp && Math.abs(dotp) < corner.dotp) {
69197 corner.dotp = Math.abs(dotp);
69200 return normalizePoint(addPoints(p, q), 0.1 * dotp * scale);
69205 function squareness(points) {
69206 return points.reduce(function(sum, val, i, array) {
69207 var dotp = normalizedDotProduct(i, array);
69209 dotp = filterDotProduct(dotp);
69210 return sum + 2.0 * Math.min(Math.abs(dotp - 1.0), Math.min(Math.abs(dotp), Math.abs(dotp + 1)));
69215 function normalizedDotProduct(i, points) {
69216 var a = points[(i - 1 + points.length) % points.length],
69218 c = points[(i + 1) % points.length],
69219 p = subtractPoints(a, b),
69220 q = subtractPoints(c, b);
69222 p = normalizePoint(p, 1.0);
69223 q = normalizePoint(q, 1.0);
69225 return p[0] * q[0] + p[1] * q[1];
69229 function subtractPoints(a, b) {
69230 return [a[0] - b[0], a[1] - b[1]];
69234 function addPoints(a, b) {
69235 return [a[0] + b[0], a[1] + b[1]];
69239 function normalizePoint(point, scale) {
69240 var vector = [0, 0];
69241 var length = Math.sqrt(point[0] * point[0] + point[1] * point[1]);
69242 if (length !== 0) {
69243 vector[0] = point[0] / length;
69244 vector[1] = point[1] / length;
69247 vector[0] *= scale;
69248 vector[1] *= scale;
69254 function filterDotProduct(dotp) {
69255 if (lowerThreshold > Math.abs(dotp) || Math.abs(dotp) > upperThreshold) {
69263 action.disabled = function(graph) {
69264 var way = graph.entity(wayId),
69265 nodes = graph.childNodes(way),
69266 points = lodash.uniq(nodes).map(function(n) { return projection(n.loc); });
69268 if (squareness(points)) {
69272 return 'not_squarish';
69279 // Split a way at the given node.
69281 // Optionally, split only the given ways, if multiple ways share
69284 // This is the inverse of `iD.actionJoin`.
69286 // For testing convenience, accepts an ID to assign to the new way.
69287 // Normally, this will be undefined and the way will automatically
69288 // be assigned a new ID.
69291 // https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/SplitWayAction.as
69293 function actionSplit(nodeId, newWayIds) {
69296 // if the way is closed, we need to search for a partner node
69297 // to split the way at.
69299 // The following looks for a node that is both far away from
69300 // the initial node in terms of way segment length and nearby
69301 // in terms of beeline-distance. This assures that areas get
69302 // split on the most "natural" points (independent of the number
69304 // For example: bone-shaped areas get split across their waist
69305 // line, circles across the diameter.
69306 function splitArea(nodes, idxA, graph) {
69307 var lengths = new Array(nodes.length),
69313 function wrap(index) {
69314 return utilWrap(index, nodes.length);
69317 function dist(nA, nB) {
69318 return geoSphericalDistance(graph.entity(nA).loc, graph.entity(nB).loc);
69321 // calculate lengths
69323 for (i = wrap(idxA+1); i !== idxA; i = wrap(i+1)) {
69324 length += dist(nodes[i], nodes[wrap(i-1)]);
69325 lengths[i] = length;
69329 for (i = wrap(idxA-1); i !== idxA; i = wrap(i-1)) {
69330 length += dist(nodes[i], nodes[wrap(i+1)]);
69331 if (length < lengths[i])
69332 lengths[i] = length;
69335 // determine best opposite node to split
69336 for (i = 0; i < nodes.length; i++) {
69337 var cost = lengths[i] / dist(nodes[idxA], nodes[i]);
69348 function split(graph, wayA, newWayId) {
69349 var wayB = osmWay({id: newWayId, tags: wayA.tags}),
69352 isArea = wayA.isArea(),
69353 isOuter = osmIsSimpleMultipolygonOuterMember(wayA, graph);
69355 if (wayA.isClosed()) {
69356 var nodes = wayA.nodes.slice(0, -1),
69357 idxA = lodash.indexOf(nodes, nodeId),
69358 idxB = splitArea(nodes, idxA, graph);
69361 nodesA = nodes.slice(idxA).concat(nodes.slice(0, idxB + 1));
69362 nodesB = nodes.slice(idxB, idxA + 1);
69364 nodesA = nodes.slice(idxA, idxB + 1);
69365 nodesB = nodes.slice(idxB).concat(nodes.slice(0, idxA + 1));
69368 var idx = lodash.indexOf(wayA.nodes, nodeId, 1);
69369 nodesA = wayA.nodes.slice(0, idx + 1);
69370 nodesB = wayA.nodes.slice(idx);
69373 wayA = wayA.update({nodes: nodesA});
69374 wayB = wayB.update({nodes: nodesB});
69376 graph = graph.replace(wayA);
69377 graph = graph.replace(wayB);
69379 graph.parentRelations(wayA).forEach(function(relation) {
69380 if (relation.isRestriction()) {
69381 var via = relation.memberByRole('via');
69382 if (via && wayB.contains(via.id)) {
69383 relation = relation.updateMember({id: wayB.id}, relation.memberById(wayA.id).index);
69384 graph = graph.replace(relation);
69387 if (relation === isOuter) {
69388 graph = graph.replace(relation.mergeTags(wayA.tags));
69389 graph = graph.replace(wayA.update({tags: {}}));
69390 graph = graph.replace(wayB.update({tags: {}}));
69396 role: relation.memberById(wayA.id).role
69399 graph = actionAddMember(relation.id, member)(graph);
69403 if (!isOuter && isArea) {
69404 var multipolygon = osmRelation({
69405 tags: lodash.extend({}, wayA.tags, {type: 'multipolygon'}),
69407 {id: wayA.id, role: 'outer', type: 'way'},
69408 {id: wayB.id, role: 'outer', type: 'way'}
69411 graph = graph.replace(multipolygon);
69412 graph = graph.replace(wayA.update({tags: {}}));
69413 graph = graph.replace(wayB.update({tags: {}}));
69420 var action = function(graph) {
69421 var candidates = action.ways(graph);
69422 for (var i = 0; i < candidates.length; i++) {
69423 graph = split(graph, candidates[i], newWayIds && newWayIds[i]);
69429 action.ways = function(graph) {
69430 var node = graph.entity(nodeId),
69431 parents = graph.parentWays(node),
69432 hasLines = lodash.some(parents, function(parent) { return parent.geometry(graph) === 'line'; });
69434 return parents.filter(function(parent) {
69435 if (wayIds && wayIds.indexOf(parent.id) === -1)
69438 if (!wayIds && hasLines && parent.geometry(graph) !== 'line')
69441 if (parent.isClosed()) {
69445 for (var i = 1; i < parent.nodes.length - 1; i++) {
69446 if (parent.nodes[i] === nodeId) {
69456 action.disabled = function(graph) {
69457 var candidates = action.ways(graph);
69458 if (candidates.length === 0 || (wayIds && wayIds.length !== candidates.length))
69459 return 'not_eligible';
69463 action.limitWays = function(_) {
69464 if (!arguments.length) return wayIds;
69473 // Create a restriction relation for `turn`, which must have the following structure:
69476 // from: { node: <node ID>, way: <way ID> },
69477 // via: { node: <node ID> },
69478 // to: { node: <node ID>, way: <way ID> },
69479 // restriction: <'no_right_turn', 'no_left_turn', etc.>
69482 // This specifies a restriction of type `restriction` when traveling from
69483 // `from.node` in `from.way` toward `to.node` in `to.way` via `via.node`.
69484 // (The action does not check that these entities form a valid intersection.)
69486 // If `restriction` is not provided, it is automatically determined by
69487 // osmInferRestriction.
69489 // If necessary, the `from` and `to` ways are split. In these cases, `from.node`
69490 // and `to.node` are used to determine which portion of the split ways become
69491 // members of the restriction.
69493 // For testing convenience, accepts an ID to assign to the new relation.
69494 // Normally, this will be undefined and the relation will automatically
69495 // be assigned a new ID.
69497 function actionRestrictTurn(turn, projection, restrictionId) {
69499 return function(graph) {
69500 var from = graph.entity(turn.from.way),
69501 via = graph.entity(turn.via.node),
69502 to = graph.entity(turn.to.way);
69504 function isClosingNode(way, nodeId) {
69505 return nodeId === way.first() && nodeId === way.last();
69508 function split(toOrFrom) {
69509 var newID = toOrFrom.newID || osmWay().id;
69510 graph = actionSplit(via.id, [newID])
69511 .limitWays([toOrFrom.way])(graph);
69513 var a = graph.entity(newID),
69514 b = graph.entity(toOrFrom.way);
69516 if (a.nodes.indexOf(toOrFrom.node) !== -1) {
69523 if (!from.affix(via.id) || isClosingNode(from, via.id)) {
69524 if (turn.from.node === turn.to.node) {
69526 from = to = split(turn.from)[0];
69527 } else if (turn.from.way === turn.to.way) {
69528 // Straight-on or circular
69529 var s = split(turn.from);
69534 from = split(turn.from)[0];
69538 if (!to.affix(via.id) || isClosingNode(to, via.id)) {
69539 to = split(turn.to)[0];
69542 return graph.replace(osmRelation({
69545 type: 'restriction',
69546 restriction: turn.restriction ||
69547 osmInferRestriction(
69555 {id: from.id, type: 'way', role: 'from'},
69556 {id: via.id, type: 'node', role: 'via'},
69557 {id: to.id, type: 'way', role: 'to'}
69563 function actionRevert(id) {
69564 var action = function(graph) {
69565 var entity = graph.hasEntity(id),
69566 base = graph.base().entities[id];
69568 if (entity && !base) { // entity will be removed..
69569 if (entity.type === 'node') {
69570 graph.parentWays(entity)
69571 .forEach(function(parent) {
69572 parent = parent.removeNode(id);
69573 graph = graph.replace(parent);
69575 if (parent.isDegenerate()) {
69576 graph = actionDeleteWay(parent.id)(graph);
69581 graph.parentRelations(entity)
69582 .forEach(function(parent) {
69583 parent = parent.removeMembersWithID(id);
69584 graph = graph.replace(parent);
69586 if (parent.isDegenerate()) {
69587 graph = actionDeleteRelation(parent.id)(graph);
69592 return graph.revert(id);
69598 function actionRotateWay(wayId, pivot, angle, projection) {
69599 return function(graph) {
69600 return graph.update(function(graph) {
69601 var way = graph.entity(wayId);
69603 lodash.uniq(way.nodes).forEach(function(id) {
69605 var node = graph.entity(id),
69606 point = projection(node.loc),
69609 radial[0] = point[0] - pivot[0];
69610 radial[1] = point[1] - pivot[1];
69613 radial[0] * Math.cos(angle) - radial[1] * Math.sin(angle) + pivot[0],
69614 radial[0] * Math.sin(angle) + radial[1] * Math.cos(angle) + pivot[1]
69617 graph = graph.replace(node.move(projection.invert(point)));
69626 * Based on https://github.com/openstreetmap/potlatch2/net/systemeD/potlatch2/tools/Straighten.as
69628 function actionStraighten(wayId, projection) {
69630 function positionAlongWay(n, s, e) {
69631 return ((n[0] - s[0]) * (e[0] - s[0]) + (n[1] - s[1]) * (e[1] - s[1]))/
69632 (Math.pow(e[0] - s[0], 2) + Math.pow(e[1] - s[1], 2));
69636 var action = function(graph) {
69637 var way = graph.entity(wayId),
69638 nodes = graph.childNodes(way),
69639 points = nodes.map(function(n) { return projection(n.loc); }),
69640 startPoint = points[0],
69641 endPoint = points[points.length-1],
69645 for (i = 1; i < points.length-1; i++) {
69646 var node = nodes[i],
69649 if (graph.parentWays(node).length > 1 ||
69650 graph.parentRelations(node).length ||
69651 node.hasInterestingTags()) {
69653 var u = positionAlongWay(point, startPoint, endPoint),
69654 p0 = startPoint[0] + u * (endPoint[0] - startPoint[0]),
69655 p1 = startPoint[1] + u * (endPoint[1] - startPoint[1]);
69658 .replace(graph.entity(node.id)
69659 .move(projection.invert([p0, p1])));
69663 if (toDelete.indexOf(node) === -1) {
69664 toDelete.push(node);
69669 for (i = 0; i < toDelete.length; i++) {
69670 graph = actionDeleteNode(toDelete[i].id)(graph);
69677 action.disabled = function(graph) {
69678 // check way isn't too bendy
69679 var way = graph.entity(wayId),
69680 nodes = graph.childNodes(way),
69681 points = nodes.map(function(n) { return projection(n.loc); }),
69682 startPoint = points[0],
69683 endPoint = points[points.length-1],
69684 threshold = 0.2 * geoEuclideanDistance(startPoint, endPoint),
69687 if (threshold === 0) {
69688 return 'too_bendy';
69691 for (i = 1; i < points.length-1; i++) {
69692 var point = points[i],
69693 u = positionAlongWay(point, startPoint, endPoint),
69694 p0 = startPoint[0] + u * (endPoint[0] - startPoint[0]),
69695 p1 = startPoint[1] + u * (endPoint[1] - startPoint[1]),
69696 dist = Math.sqrt(Math.pow(p0 - point[0], 2) + Math.pow(p1 - point[1], 2));
69698 // to bendy if point is off by 20% of total start/end distance in projected space
69699 if (isNaN(dist) || dist > threshold) {
69700 return 'too_bendy';
69709 // Remove the effects of `turn.restriction` on `turn`, which must have the
69710 // following structure:
69713 // from: { node: <node ID>, way: <way ID> },
69714 // via: { node: <node ID> },
69715 // to: { node: <node ID>, way: <way ID> },
69716 // restriction: <relation ID>
69719 // In the simple case, `restriction` is a reference to a `no_*` restriction
69720 // on the turn itself. In this case, it is simply deleted.
69722 // The more complex case is where `restriction` references an `only_*`
69723 // restriction on a different turn in the same intersection. In that case,
69724 // that restriction is also deleted, but at the same time restrictions on
69725 // the turns other than the first two are created.
69727 function actionUnrestrictTurn(turn) {
69728 return function(graph) {
69729 return actionDeleteRelation(turn.restriction)(graph);
69735 var index$16 = Object.freeze({
69736 d3combobox: d3combobox,
69737 d3geoTile: d3geoTile,
69738 d3keybinding: d3keybinding
69741 /* export some legacy symbols: */
69742 var Connection = services.osm;
69748 var iD = Object.freeze({
69749 Connection: Connection,
69753 Context: coreContext,
69754 setAreaKeys: setAreaKeys,
69755 Difference: coreDifference,
69756 Graph: coreGraph$$1,
69757 History: coreHistory,
69759 Entity: osmEntity$$1,
69761 Relation: osmRelation,
69763 BackgroundSource: rendererBackgroundSource,
69764 Background: rendererBackground,
69765 Features: rendererFeatures,
69767 TileLayer: rendererTileLayer,
69768 Detect: utilDetect,
69769 actionAddEntity: actionAddEntity,
69770 actionAddMember: actionAddMember,
69771 actionAddMidpoint: actionAddMidpoint,
69772 actionAddVertex: actionAddVertex,
69773 actionChangeMember: actionChangeMember,
69774 actionChangePreset: actionChangePreset,
69775 actionChangeTags: actionChangeTags,
69776 actionCircularize: actionCircularize,
69777 actionConnect: actionConnect,
69778 actionCopyEntities: actionCopyEntities,
69779 actionDeleteMember: actionDeleteMember,
69780 actionDeleteMultiple: actionDeleteMultiple,
69781 actionDeleteNode: actionDeleteNode,
69782 actionDeleteRelation: actionDeleteRelation,
69783 actionDeleteWay: actionDeleteWay,
69784 actionDeprecateTags: actionDeprecateTags,
69785 actionDiscardTags: actionDiscardTags,
69786 actionDisconnect: actionDisconnect,
69787 actionJoin: actionJoin,
69788 actionMerge: actionMerge,
69789 actionMergePolygon: actionMergePolygon,
69790 actionMergeRemoteChanges: actionMergeRemoteChanges,
69791 actionMove: actionMove,
69792 actionMoveNode: actionMoveNode,
69793 actionNoop: actionNoop,
69794 actionOrthogonalize: actionOrthogonalize,
69795 actionRestrictTurn: actionRestrictTurn,
69796 actionReverse: actionReverse,
69797 actionRevert: actionRevert,
69798 actionRotateWay: actionRotateWay,
69799 actionSplit: actionSplit,
69800 actionStraighten: actionStraighten,
69801 actionUnrestrictTurn: actionUnrestrictTurn,
69802 behaviorAddWay: behaviorAddWay,
69803 behaviorBreathe: behaviorBreathe,
69804 behaviorCopy: behaviorCopy,
69805 behaviorDrag: behaviorDrag,
69806 behaviorDrawWay: behaviorDrawWay,
69807 behaviorDraw: behaviorDraw,
69808 behaviorEdit: behaviorEdit,
69809 behaviorHash: behaviorHash,
69810 behaviorHover: behaviorHover,
69811 behaviorLasso: behaviorLasso,
69812 behaviorPaste: behaviorPaste,
69813 behaviorSelect: behaviorSelect,
69814 behaviorTail: behaviorTail,
69815 coreContext: coreContext,
69816 coreDifference: coreDifference,
69817 coreGraph: coreGraph$$1,
69818 coreHistory: coreHistory,
69819 coreTree: coreTree,
69821 dataWikipedia: dataWikipedia,
69822 dataFeatureIcons: dataFeatureIcons,
69823 dataSuggestions: dataSuggestions,
69824 dataAddressFormats: dataAddressFormats,
69825 dataDeprecated: dataDeprecated,
69826 dataDiscarded: dataDiscarded,
69827 dataLocales: dataLocales,
69828 dataPhoneFormats: dataPhoneFormats,
69829 dataImperial: dataImperial,
69830 dataDriveLeft: dataDriveLeft,
69832 geoRoundCoords: geoRoundCoords,
69833 geoInterp: geoInterp,
69834 geoCross: geoCross,
69835 geoEuclideanDistance: geoEuclideanDistance,
69836 geoLatToMeters: geoLatToMeters,
69837 geoLonToMeters: geoLonToMeters,
69838 geoMetersToLat: geoMetersToLat,
69839 geoMetersToLon: geoMetersToLon,
69840 geoOffsetToMeters: geoOffsetToMeters,
69841 geoMetersToOffset: geoMetersToOffset,
69842 geoSphericalDistance: geoSphericalDistance,
69843 geoEdgeEqual: geoEdgeEqual,
69844 geoAngle: geoAngle,
69845 geoChooseEdge: geoChooseEdge,
69846 geoLineIntersection: geoLineIntersection,
69847 geoPathIntersections: geoPathIntersections,
69848 geoPointInPolygon: geoPointInPolygon,
69849 geoPolygonContainsPolygon: geoPolygonContainsPolygon,
69850 geoPolygonIntersectsPolygon: geoPolygonIntersectsPolygon,
69851 geoPathLength: geoPathLength,
69852 geoExtent: geoExtent$$1,
69853 geoRawMercator: geoRawMercator,
69854 modeAddArea: modeAddArea$$1,
69855 modeAddLine: modeAddLine$$1,
69856 modeAddPoint: modeAddPoint$$1,
69857 modeBrowse: modeBrowse$$1,
69858 modeDragNode: modeDragNode$$1,
69859 modeDrawArea: modeDrawArea,
69860 modeDrawLine: modeDrawLine,
69861 modeMove: modeMove$$1,
69862 modeRotateWay: modeRotateWay$$1,
69863 modeSave: modeSave$$1,
69864 modeSelect: modeSelect,
69865 operationCircularize: operationCircularize,
69866 operationContinue: operationContinue,
69867 operationDelete: operationDelete,
69868 operationDisconnect: operationDisconnect,
69869 operationMerge: operationMerge,
69870 operationMove: operationMove,
69871 operationOrthogonalize: operationOrthogonalize,
69872 operationReverse: operationReverse,
69873 operationRotate: operationRotate,
69874 operationSplit: operationSplit,
69875 operationStraighten: operationStraighten,
69876 osmEntity: osmEntity$$1,
69878 osmRelation: osmRelation,
69880 osmIntersection: osmIntersection,
69882 osmInferRestriction: osmInferRestriction,
69883 osmLanes: osmLanes,
69884 osmIsSimpleMultipolygonOuterMember: osmIsSimpleMultipolygonOuterMember,
69885 osmSimpleMultipolygonOuterMember: osmSimpleMultipolygonOuterMember,
69886 osmJoinWays: osmJoinWays,
69887 osmOneWayTags: osmOneWayTags,
69888 osmPavedTags: osmPavedTags,
69889 osmIsInterestingTag: osmIsInterestingTag,
69890 presetCategory: presetCategory,
69891 presetCollection: presetCollection,
69892 presetField: presetField,
69893 presetPreset: presetPreset,
69894 presetIndex: presetIndex,
69895 rendererBackgroundSource: rendererBackgroundSource,
69896 rendererBackground: rendererBackground,
69897 rendererFeatures: rendererFeatures,
69898 rendererMap: rendererMap,
69899 rendererTileLayer: rendererTileLayer,
69900 services: services,
69901 svgAreas: svgAreas$$1,
69902 svgDebug: svgDebug,
69906 svgLabels: svgLabels,
69907 svgLayers: svgLayers,
69908 svgLines: svgLines$$1,
69909 svgMapillaryImages: svgMapillaryImages,
69910 svgMapillarySigns: svgMapillarySigns,
69911 svgMidpoints: svgMidpoints$$1,
69912 svgOneWaySegments: svgOneWaySegments,
69915 svgPointTransform: svgPointTransform,
69916 svgPoints: svgPoints$$1,
69917 svgRelationMemberTags: svgRelationMemberTags,
69918 svgTagClasses: svgTagClasses,
69919 svgTurns: svgTurns,
69920 svgVertices: svgVertices$$1,
69921 uiFields: uiFields,
69922 uiFieldDefaultcheck: uiFieldCheck,
69923 uiFieldCheck: uiFieldCheck,
69924 uiFieldTypeCombo: uiFieldCombo,
69925 uiFieldMultiCombo: uiFieldCombo,
69926 uiFieldNetworkCombo: uiFieldCombo,
69927 uiFieldCombo: uiFieldCombo,
69928 uiFieldUrl: uiFieldText,
69929 uiFieldNumber: uiFieldText,
69930 uiFieldTel: uiFieldText,
69931 uiFieldEmail: uiFieldText,
69932 uiFieldText: uiFieldText,
69933 uiFieldAccess: uiFieldAccess,
69934 uiFieldAddress: uiFieldAddress,
69935 uiFieldCycleway: uiFieldCycleway,
69936 uiFieldLanes: uiFieldLanes,
69937 uiFieldLocalized: uiFieldLocalized,
69938 uiFieldMaxspeed: uiFieldMaxspeed,
69939 uiFieldRadio: uiFieldRadio,
69940 uiFieldRestrictions: uiFieldRestrictions,
69941 uiFieldTextarea: uiFieldTextarea,
69942 uiFieldWikipedia: uiFieldWikipedia,
69945 uiAccount: uiAccount,
69946 uiAttribution: uiAttribution,
69947 uiBackground: uiBackground,
69949 uiCommit: uiCommit,
69950 uiConfirm: uiConfirm,
69951 uiConflicts: uiConflicts,
69952 uiContributors: uiContributors,
69953 uiDisclosure: uiDisclosure,
69954 uiEntityEditor: uiEntityEditor,
69955 uiFeatureInfo: uiFeatureInfo,
69956 uiFeatureList: uiFeatureList,
69958 uiFullScreen: uiFullScreen,
69959 uiGeolocate: uiGeolocate,
69962 uiInspector: uiInspector,
69964 uiLoading: uiLoading,
69965 uiMapData: uiMapData,
69966 uiMapInMap: uiMapInMap,
69969 uiNotice: uiNotice,
69970 uiPreset: uiPreset,
69971 uiPresetIcon: uiPresetIcon,
69972 uiPresetList: uiPresetList,
69973 uiRadialMenu: uiRadialMenu,
69974 uiRawMemberEditor: uiRawMemberEditor,
69975 uiRawMembershipEditor: uiRawMembershipEditor,
69976 uiRawTagEditor: uiRawTagEditor,
69977 uiRestore: uiRestore,
69980 uiSelectionList: uiSelectionList,
69981 uiSidebar: uiSidebar,
69982 uiSourceSwitch: uiSourceSwitch,
69983 uiSpinner: uiSpinner,
69984 uiSplash: uiSplash,
69985 uiStatus: uiStatus,
69986 uiSuccess: uiSuccess,
69987 uiTagReference: uiTagReference,
69988 uiToggle: uiToggle,
69989 uiTooltipHtml: uiTooltipHtml,
69990 uiUndoRedo: uiUndoRedo,
69991 uiViewOnOSM: uiViewOnOSM,
69993 utilTagText: utilTagText,
69994 utilEntitySelector: utilEntitySelector,
69995 utilEntityOrMemberSelector: utilEntityOrMemberSelector,
69996 utilDisplayName: utilDisplayName,
69997 utilDisplayType: utilDisplayType,
69998 utilStringQs: utilStringQs,
69999 utilQsString: utilQsString,
70000 utilPrefixDOMProperty: utilPrefixDOMProperty,
70001 utilPrefixCSSProperty: utilPrefixCSSProperty,
70002 utilSetTransform: utilSetTransform,
70003 utilEditDistance: utilEditDistance,
70004 utilFastMouse: utilFastMouse,
70005 utilGetPrototypeOf: utilGetPrototypeOf,
70006 utilAsyncMap: utilAsyncMap,
70007 utilWrap: utilWrap,
70008 utilFunctor: utilFunctor,
70009 utilSessionMutex: utilSessionMutex,
70010 utilSuggestNames: utilSuggestNames,
70011 utilTriggerEvent: utilTriggerEvent,
70012 utilGetSetValue: utilGetSetValue,
70013 d3combobox: d3combobox,
70014 d3geoTile: d3geoTile,
70015 d3keybinding: d3keybinding,
70016 validationDeprecatedTag: validationDeprecatedTag,
70017 validationManyDeletions: validationManyDeletions,
70018 validationMissingTag: validationMissingTag,
70019 validationTagSuggestsArea: validationTagSuggestsArea
70025 //# sourceMappingURL=iD.js.map